Переглянути джерело

Version without proprietary binaries

xchwarze 2 роки тому
коміт
19341aa6ae
46 змінених файлів з 3839 додано та 0 видалено
  1. 106 0
      README.md
  2. BIN
      assets/binance-qr.png
  3. BIN
      assets/logo.png
  4. BIN
      assets/patreon.png
  5. BIN
      assets/termidor-darkmode-5gscan.png
  6. BIN
      assets/termidor-mipsel.png
  7. BIN
      assets/termidor-terminal.png
  8. 171 0
      build.md
  9. 219 0
      devices.md
  10. 64 0
      files/common/etc/20-sd-universal
  11. 12 0
      files/common/etc/30-fix_wifi
  12. 94 0
      files/common/etc/90-firewall.sh
  13. 8 0
      files/common/etc/92-system.sh
  14. 24 0
      files/common/etc/95-network.sh
  15. 51 0
      files/common/etc/97-pineapple.sh
  16. 23 0
      files/common/etc/banner
  17. 5 0
      files/common/etc/shadow
  18. 14 0
      files/common/etc/wpc-tools
  19. 84 0
      files/common/etc/wps
  20. 5 0
      files/common/lib/pineapple.keep
  21. 20 0
      files/common/pineapple/config.php.nano
  22. 20 0
      files/common/pineapple/config.php.tetra
  23. BIN
      files/common/pineapple/favicon-16x16.png
  24. BIN
      files/common/pineapple/favicon-32x32.png
  25. BIN
      files/common/pineapple/favicon.ico
  26. 54 0
      files/common/sbin/led
  27. 1533 0
      files/common/usr/airmon-ng
  28. 190 0
      files/common/usr/wpc-tools
  29. 2 0
      files/mips/customfeeds.conf
  30. BIN
      files/mips/python/encodings/__init__.pyc
  31. BIN
      files/mips/python/encodings/aliases.pyc
  32. BIN
      files/mips/python/encodings/base64_codec.pyc
  33. BIN
      files/mips/python/encodings/hex_codec.pyc
  34. 2 0
      files/mipsel/customfeeds.conf
  35. BIN
      files/mipsel/python/encodings/__init__.pyc
  36. BIN
      files/mipsel/python/encodings/aliases.pyc
  37. BIN
      files/mipsel/python/encodings/base64_codec.pyc
  38. BIN
      files/mipsel/python/encodings/hex_codec.pyc
  39. 118 0
      lists/nano.filelist
  40. 112 0
      lists/tetra.filelist
  41. 112 0
      lists/universal.filelist
  42. 171 0
      tools/builder.sh
  43. 72 0
      tools/copier.sh
  44. 103 0
      tools/dependencies-install.sh
  45. 291 0
      tools/fs-patcher.sh
  46. 159 0
      tools/opkg-parser.php

+ 106 - 0
README.md

@@ -0,0 +1,106 @@
+![Project Logo](assets/logo.png)
+
+# Wifi Pineapple Cloner v4
+
+The Pineapple NANO and TETRA are excellent security hardware but in 2020 they reached their end of life.<br>
+So to give a new life to this platform on modern hardware I developed these scripts to port it to different routers.<br>
+
+Sometime between 2019 and 2020 we started using the private beta of this project which my friends called "Pineapple Termidor".<br>
+So at the time of redoing this project I decided to rescue the original name from forgotten 🤣
+
+
+## About this project
+
+This project is the result of everything I've experienced from 2018 to 2022 to successfully clone the NANO and TETRA in any hardware.<br>
+
+For this I've develop:
+* The method of patching the file system with the minimum to be able to work. For this I created the list of files to copy and the script that copies them.
+* A script to patch the file system to work on any hardware.
+* Completely updated [panel](https://github.com/xchwarze/wifi-pineapple-panel) with fixes and improvements.
+* Completely updated [packages repository](https://github.com/xchwarze/wifi-pineapple-community-packages) ([build](https://github.com/xchwarze/wifi-pineapple-community/tree/main/packages)).
+* New [module repository](https://github.com/xchwarze/wifi-pineapple-community/tree/main/modules).
+* And some new modules that are basic to use a device like this nowadays. New modules: [PMKIDAttack](https://github.com/xchwarze/wifi-pineapple-community/tree/main/modules/src/PMKIDAttack) and [Terminal](https://github.com/xchwarze/wifi-pineapple-community/tree/main/modules/src/Terminal)
+* I also carefully checked every dependency that was installed on the device in order to have more free space on the main partition.
+
+![Panel](assets/termidor-mipsel.png)
+
+
+## Builds
+
+You can find the complete steps to build this project in [this document](build.md). I also added several important notes about this.
+<br>
+
+
+## Supported devices
+
+There are 211 devices supported by the project. You can see the full [list here](devices.md).
+<br>
+
+Also I made a second repo for [downloads](https://github.com/xchwarze/wifi-pineapple-cloner-builds) where you can find the firmwares already made for the most common devices of the Supported devices list.
+<br>
+
+
+## What differences are there with other methods using by firmwares that I can download from the internet?
+
+All the firmwares found on the internet have been created using the [securityaddicted method](https://www.securityaddicted.com/2016/11/17/weaponizing-gl-inet-gl-ar150/), which involves duplicating the entire original file system. However, this approach consumes excessive space and often leads to instability. As a result, I have developed a new and improved method.
+
+I introduced this new method method during my presentations at EkoParty 2020 and DragonJar 2021. You can access the materials from those [presentations here](https://github.com/indetectables-net/embedded).
+
+In 2021, an [idiot named Samy Younsi](https://github.com/xchwarze/wifi-pineapple-cloner/issues/26), shamelessly plagiarized the method I had developed and presented at conferences. Months later, he adapted it to Python using the Wifi Pineapple Cloner v1 version and continued spreading it as his own creation.
+
+Throughout 2022, I debugged the method and mastered its usage, enabling me to successfully port the pineapple to any hardware and achieve flawless functionality, identical to that of the original device.
+
+Therefore, the most refined method I have devised not only significantly reduces the firmware's file size but also guarantees stability comparable to the original hardware.<br>
+<br>
+
+
+## Install steps
+
+1. Install OpenWrt version 19.07.7 on your router.
+<br>
+
+2. Use SCP to upload the [firmware image](https://github.com/xchwarze/wifi-pineapple-cloner-builds) in your device.
+```bash
+scp gl-ar750s-universal-sysupgrade.bin root@192.168.1.1:/tmp 
+root@192.168.1.1's password: 
+gl-ar750s-universal-sysupgrade.bin                                                                        100%   13MB   2.2MB/s   00:05 
+```
+<br>
+
+3. Once the image is uploaded, execute sysupgrade command to update firmware. Wait few minutes until the device install the new firmware. 
+```bash
+ssh root@192.168.1.1
+sysupgrade -n -F /tmp/gl-ar750s-universal-sysupgrade.bin
+```
+<br>
+
+4. Enter to pineapple panel and enjoy! `http://172.16.42.1:1471/`
+
+In the [download](https://github.com/xchwarze/wifi-pineapple-cloner-builds) repo you can find some debugging tips if you have problems.
+<br>
+
+5. Once installed, the project has a tool that helps us to do several things.
+For example you can use it to change the panel theme with this command:
+```bash
+wpc-tools theme_install
+```
+
+
+## Recomended setup
+
+1. [GL-AR150](https://www.gl-inet.com/products/gl-ar150/) or [GL-AR750S](https://www.gl-inet.com/products/gl-ar750s)
+
+2. USB 2.0 [2 ports hub](https://www.ebay.com/itm/144520475350)
+
+3. Generic [RT5370 WIFI adapter](https://www.ebay.com/itm/284904442887) or [MT7612U WIFI adapter](https://www.ebay.com/itm/175219205235) **you're really going to need this on hardware that doesn't have two wifi adapters**
+
+4. Please support Hak5 work and buy the new hardware!
+
+
+## Patreon and Tips!
+
+Those who want to help buy testing hardware or just give me a tip, you can do it by sending donations to my Binance account.
+I also made a [Patreon](https://www.patreon.com/xchwarze) account where I share private builds and tests. Here you can find updates for the **Pineapple Nano** and builds to **improve stability** on 5g.
+
+[![patreon](assets/patreon.png)](https://www.patreon.com/xchwarze)
+![binance-qr](assets/binance-qr.png)

BIN
assets/binance-qr.png


BIN
assets/logo.png


BIN
assets/patreon.png


BIN
assets/termidor-darkmode-5gscan.png


BIN
assets/termidor-mipsel.png


BIN
assets/termidor-terminal.png


+ 171 - 0
build.md

@@ -0,0 +1,171 @@
+## Automatic Build steps
+
+All these steps are automated in `dependencies-install.sh` and `builder.sh`
+```bash
+chmod +x tools/*.sh
+tools/dependencies-install.sh openwrt-deps-mips
+sudo tools/dependencies-install.sh ubuntu-deps
+tools/builder.sh mips universal imagebuilder-19.07.7-ar71xx-generic gl-ar750s
+```
+<br>
+
+
+## Manual Build steps
+
+1. Unpack firmware for get file system
+```bash
+# install last version of binwalk first!
+# https://github.com/ReFirmLabs/binwalk
+
+# tetra
+#wget https://www.wifipineapple.com/downloads/tetra/latest -O basefw.bin
+#binwalk basefw.bin -e 
+#binwalk _basefw.bin.extracted/sysupgrade-pineapple-tetra/root -e --preserve-symlinks
+#mv _basefw.bin.extracted/sysupgrade-pineapple-tetra/_root.extracted/squashfs-root/ rootfs-base
+
+# nano
+wget https://www.wifipineapple.com/downloads/nano/latest -O basefw.bin
+binwalk basefw.bin -e --preserve-symlinks
+mv _basefw.bin.extracted/squashfs-root/ rootfs-base
+```
+
+2. Get opkg packages list from openwrt file system
+```bash
+# get packages list
+php tools/opkg-parser.php rootfs-base/usr/lib/opkg/status
+```
+
+3. Generate openwrt extra files
+```bash
+# copy pineapple files
+chmod +x tools/copier.sh
+tools/copier.sh lists/nano.filelist rootfs-base rootfs
+
+# fix files
+chmod +x tools/fs-patcher.sh
+tools/fs-patcher.sh mips rootfs nano
+```
+
+4. Build your custom build
+```bash
+# for this poc use openwrt imagebuilder v19.07.2 for ar71xx
+wget https://downloads.openwrt.org/releases/19.07.2/targets/ar71xx/generic/openwrt-imagebuilder-19.07.2-ar71xx-generic.Linux-x86_64.tar.xz
+tar xJf openwrt-imagebuilder-19.07.2-ar71xx-generic.Linux-x86_64.tar.xz
+cd openwrt-imagebuilder-19.07.2-ar71xx-generic.Linux-x86_64
+
+# based on step 2 data!
+# ar71xx profile name: gl-ar150
+# ath79 profile name: glinet_gl-ar150
+make image PROFILE=gl-ar150 PACKAGES="at autossh base-files block-mount ca-certificates chat dnsmasq e2fsprogs ethtool firewall hostapd-utils ip6tables iperf3 iwinfo kmod-crypto-manager kmod-fs-ext4 kmod-fs-nfs kmod-fs-vfat kmod-gpio-button-hotplug kmod-ipt-offload kmod-leds-gpio kmod-ledtrig-default-on kmod-ledtrig-netdev kmod-ledtrig-timer kmod-mt76x2u kmod-nf-nathelper kmod-rt2800-usb kmod-rtl8187 kmod-rtl8192cu kmod-scsi-generic kmod-usb-acm kmod-usb-net-asix kmod-usb-net-asix-ax88179 kmod-usb-net-qmi-wwan kmod-usb-net-rndis kmod-usb-net-sierrawireless kmod-usb-net-smsc95xx kmod-usb-ohci kmod-usb-storage-extras kmod-usb-uhci kmod-usb2 libbz2-1.0 libcurl4 libelf1 libffi libgmp10 libiconv-full2 libintl libltdl7 libnet-1.2.x libnl200 libreadline8 libustream-mbedtls20150806 libxml2 logd macchanger mt7601u-firmware mtd nano ncat netcat nginx odhcp6c odhcpd-ipv6only openssh-client openssh-server openssh-sftp-server openssl-util php7-cgi php7-fpm php7-mod-hash php7-mod-json php7-mod-mbstring php7-mod-openssl php7-mod-session php7-mod-sockets php7-mod-sqlite3 ppp ppp-mod-pppoe procps-ng-pkill procps-ng-ps python-logging python-openssl python-sqlite3 rtl-sdr ssmtp tcpdump uboot-envtools uci uclibcxx uclient-fetch urandom-seed urngd usb-modeswitch usbreset usbutils wget wireless-tools wpad busybox libatomic1 libstdcpp6 -wpad-basic -dropbear" FILES=../rootfs
+cp bin/targets/ar71xx/generic/openwrt-19.07.2-ar71xx-generic-gl-ar150-squashfs-sysupgrade.bin ../gl-ar150-pineapple-nano.bin
+```
+
+5. Flash the target hardware with this custom firmware!
+```bash
+# Use SCP to upload the image in your device
+scp gl-ar150-pineapple-nano.bin root@192.168.1.1:/tmp 
+
+# Once the image is uploaded execute sysupgrade command to update firmware
+ssh root@192.168.1.1
+sysupgrade -n -F /tmp/gl-ar150-pineapple-nano.bin
+```
+<br>
+
+
+## Original Harware specifications
+
+#### WiFi Pineapple NANO specifications:
+- SoC: Atheros AR9331 (400 MHz)
+- RAM: 64 MB (DDR2)
+- FLASH: 16 MB
+- WiFi: 1T1R AR9331 (built-in), 1T1R AR9271 (built-in via USB bus)
+- Ethernet: 1x FE over USB (ASIX AX88772A)
+- Ports: 2x RP-SMA for antennas, 1x USB 2.0 (host), 1x micro SD
+- Power: USB 5 V, 1.5 A
+- Other: status LED, reset button
+
+#### WiFi Pineapple TETRA specifications:
+- SoC: Atheros AR9344 (533 MHz MIPS 74K)
+- RAM: 64 MB (DDR2)
+- FLASH: 2 GB NAND Flash
+- WiFi: Atheros AR9344 + Atheros AR9580
+- Ethernet: 1 x RJ45 Ethernet, 1x FE over USB (ASIX AX88772A)
+- Ports: 4x RP-SMA Antenna, 1 x USB 2.0 (host)
+- Power: DC Barrel 12V/2A. Accepts power from any combination of sources; DC Barrel Port, USB ETH port, USB UART port.
+- Other: status LED, reset button
+<br>
+
+
+## Important notes
+
+1. The original hardware is designed to have 2 Wi-Fi cards and have at least 2 gigabytes of disk space!
+<br>
+
+To meet these requirements in your hard you will have to:
+* Add a pendrive. The pendrive has to be formatted from the pineapple panel `Advanced > USB & Storage > Format SD Card`
+* In case your hardware does not have a second Wi-Fi adapter you will have to add one of the recommended ones (RT5370 or MT7612U).
+* You can connect both with a usb hub!
+<br>
+
+2. As tetra is made to be used on hardware with 32 MB of flash I had to cut some dependencies from the default installation.
+<br>
+
+These dependencies will be installed automatically when the pinapple is connected to the internet and booting.
+<br>
+
+If you want to manually run this process `wpc-tools missing_packages` or `opkg update && opkg --dest sd install python-logging python-openssl python-sqlite3 python-codecs`
+<br>
+
+Without these dependencies you will not be able to use the live scan type and some modules.
+However, you will be able to use the timed scans and the rest of the tools.
+<br>
+
+3. The original pineapple binaries are compiled with mips24kc and BE endianness.
+So your target hardware must support the instructionset with this endianness. Check this in the [openwrt list of hardware](https://openwrt.org/docs/techref/instructionset/mips_24kc).
+<br>
+
+4. The original pineapple binaries are compiled with SSP ([Stack-Smashing Protection](https://openwrt.org/docs/guide-user/security/security-features)) 
+Your version has to support it, so as not to have this type of errors:
+```bash
+[    7.383577] kmodloader: loading kernel modules from /etc/modules-boot.d/*
+[    8.052737] crypto_hash: Unknown symbol __stack_chk_guard (err 0)
+[    8.057461] crypto_hash: Unknown symbol __stack_chk_fail (err 0)
+```
+<br>
+
+5. WiFi Pineapple use a modified version of:
+```bash
+/lib/netifd/wireless/mac80211.sh
+/lib/netifd/hostapd.sh
+/lib/wifi/mac80211.sh
+```
+You may have to make yours based on these.
+<br>
+
+6. Busybox applets list:
+```
+# openwrt: used 118 applets
+[ [[ ash awk basename brctl bunzip2 bzcat cat chgrp chmod chown chroot clear cmp cp crond crontab cut date dd df dirname dmesg du echo egrep env expr false fgrep find flock free fsync grep gunzip gzip halt head hexdump hwclock id ifconfig ip kill killall less ln lock logger login ls md5sum mkdir mkfifo mknod mkswap mktemp mount mv nc netmsg netstat nice nslookup ntpd passwd pgrep pidof ping ping6 pivot_root poweroff printf ps pwd readlink reboot reset rm rmdir route sed seq sh sha256sum sleep sort start-stop-daemon strings swapoff swapon switch_root sync sysctl tail tar tee test time top touch tr traceroute traceroute6 true udhcpc umount uname uniq uptime vi wc which xargs yes zcat
+
+# nano: used 116 applets
+[ [[ ash awk basename bash brctl cat chgrp chmod chown chroot clear cmp cp crond crontab cut date dd df dirname dmesg du echo egrep env expr false fdisk fgrep find flock free fsync grep gunzip gzip halt head hexdump hwclock id ifconfig ip kill killall less ln lock logger login ls md5sum mkdir mkfifo mknod mkswap mktemp mount mv nc netmsg netstat nice nslookup ntpd passwd pgrep pidof ping ping6 pivot_root poweroff printf ps pwd readlink reboot reset rm rmdir route sed seq sh sha256sum sleep sort start-stop-daemon swapoff swapon switch_root sync sysctl tail tar tee test time top touch tr traceroute true udhcpc umount uname uniq uptime uuencode vi wc which xargs yes
+
+# tetra: used 120 applets
+[ [[ ash awk basename brctl bunzip2 bzcat cat chgrp chmod chown chroot clear cmp cp crond crontab cut date dd df dirname dmesg du echo egrep env expr false fdisk fgrep find flock free fsync grep gunzip gzip halt head hexdump hwclock id ifconfig ip kill killall less ln lock logger login ls md5sum mkdir mkfifo mknod mkswap mktemp mount mv nc netmsg netstat nice nslookup ntpd passwd pgrep pidof ping ping6 pivot_root poweroff printf ps pwd readlink reboot reset rm rmdir route sed seq sh sha256sum sleep sort start-stop-daemon strings swapoff swapon switch_root sync sysctl tail tar tee test time top touch tr traceroute traceroute6 true udhcpc umount uname uniq uptime uuencode vi wc which xargs yes zcat
+```
+
+Diferences with Openwrt Busybox build
+```
+Nano build
+--------------------
+Remove: bunzip2 bzcat strings traceroute6 zcat
+Add: bash fdisk uuencode
+
+Tetra build
+--------------------
+Remove: (nothing was removed)
+Add: fdisk uuencode
+```
+
+If you don't want to do a custom Busybox build you can install `fdisk` and `mpack`.
+Don't forget to refactor the uses of `uuencode` with `mpack`! (reporting script)<br>

+ 219 - 0
devices.md

@@ -0,0 +1,219 @@
+# Devices list
+
+The list of compatible devices is made with the data provided by OpenWRT. The criteria used to generate this list were that they are available in OpenWRT 19 and have the same capabilities as the original hardware.<br>
+**OpenWRT data may be incorrect for some devices.**
+<br><br>
+
+Brand | Device | Type | CPU (MHz) | Flash (MB) | RAM (MB) | Architecture | Availability |
+-------------|-------------|-----------|-----------|-----------|-----------|-----------|-----------|
+8devices | Carambola 2  | Single Board Computer | 400 | 16 | 64 | mips_24kc | Available 2019
+8devices | Lima  | Single Board Computer | 650 | 32 | 64 | mips_24kc | Available 2019
+8devices | Rambutan  | Single Board Computer | 720 | 128NAND | 128 | mips_24kc | Available 2019
+Abicom International | Scorpion SC300M  | Single Board Computer | 700 | 16 | 256 | mips_24kc | Available 2020
+Aerohive | AP121  | WiFi AP | 560 | 128NAND | 128 | mips_24kc | Discontinued 2017
+Afoundry | EW1200  | WiFi Router | 880 | 16 | 128 | mipsel_24kc | Discontinued 2019
+ALFA Network | AC1200RM  | WiFi Router | 580 | 16 | 64 | mipsel_24kc | Discontinued
+ALFA Network | Hornet-UB x2  | Travel Router | 400 | 16 | 64 | mips_24kc | Discontinued
+ALFA Network | R36A  | WiFi Router | 650 | 16 | 64 | mips_24kc | Available 2019
+ALLNET | ALL5002  | Single Board Computer | 400 | 32 | 64 | mipsel_24kc | Available 2019
+Arcadyan / Astoria | VGV7510KW22 (o2 Box 6431)  | WiFi Router | 500 | 16 | 64 | mips_24kc | unknown 2018
+Arcadyan / Astoria | ARV7519RW22 (Livebox 2.1)  | WiFi Router | 500 | 32 | 128 | mips_24kc | unknown 2018
+Arcadyan / Astoria | Easybox 904 LTE  | WiFi Router | 500 | 512 | 128 | mips_24kc | unknown 2018
+Arcadyan / Astoria | VGV7519KW (KPN Experia Box v8) R01 | WiFi Router | 500 | 16 | 64 | mips_24kc | unknown 2018
+Arcadyan / Astoria | VGV7519KW (KPN Experia Box v8) R02 | WiFi Router | 500 | 16 | 64 | mips_24kc | unknown 2018
+Arduino.cc | Yun  | Single Board Computer | 400 | 16,microSDHC | 64 | mips_24kc | Discontinued 2016
+AsiaRF | AP7621-002  | Router | 880 | 16 | 512 | mipsel_24kc | Available 2020
+ASUS | RT-AC51U  | WiFi Router | 580 | 16 | 64 | mipsel_24kc | Available 2019
+ASUS | RT-AC57U v1 | WiFi Router | 880 | 16 | 128 | mipsel_24kc | Available 2019
+ASUS | RT-N14U C1 | WiFi Router | 600 | 16 | 64 | mipsel_24kc | Discontinued 2016
+AVM | FRITZ!Box 7360 SL  | WiFi Router | 500 | 16,32 | 128 | mips_24kc | Discontinued
+AVM | FRITZ!Box 7362 SL  | WiFi Router | 500 | 128NAND | 128 | mips_24kc | Discontinued
+AVM | FRITZ!Box WLAN 3370  | WiFi Router | 500 | 128NAND,512NAND | 128 | mips_24kc | Discontinued
+AVM | FRITZ!Box 4020  | WiFi Router | 750 | 16 | 128 | mips_24kc | Available 2019
+BDCOM | WAP2100-SK  | WiFi Router | 580 | 16,SD | 128 | mipsel_24kc | unknown 2018
+Beeline | Smartbox GIGA  | WiFi Router | 880 | 128NAND | 256 | mipsel_24kc | Available 2022
+Beeline | SmartBox TURBO+  | WiFi Router | 880 | 128 | 128 | mipsel_24kc | unknown 2022
+Belkin | F9K1115 (AC 1750 DB) v2 | WiFi Router | 720 | 16 | 128 | mips_24kc | Discontinued 2016
+Blueendless | U35WF  | NAS | 580 | 16 | 64 | mipsel_24kc | Available 2018
+Blueendless | U25AWF HSEN-KI-300M-HDD-V3.0 | NAS | 580 | 16 | 64 | mipsel_24kc | Available 2018
+BT | Home Hub 5 Type A | WiFi Router | 500 | 128NAND | 128 | mips_24kc | unknown 2018
+Buffalo | WZR-HP-G300NH v1 | WiFi Router | 400 | 32 | 64 | mips_24kc | Discontinued 2016
+Buffalo | WZR-HP-G300NH2 A0A0,A0A1,A1A0,C1A0 | WiFi Router | 400 | 32 | 64 | mips_24kc | Discontinued 2016
+Buffalo | WZR-HP-G302H A1A0 | WiFi Router | 400 | 32 | 64 | mips_24kc | unknown 2018
+Buffalo | WZR-HP-G450H v1 | WiFi Router | 400 | 32 | 64 | mips_24kc | Discontinued 2016
+Buffalo | WZR-300HP  | WiFi Router | 400 | 32 | 64 | mips_24kc | Discontinued 2016
+Buffalo | WZR-600DHP  | WiFi Router | 680 | 32 | 128 | mips_24kc | Discontinued
+Buffalo | WZR-HP-AG300H v1 | WiFi Router | 680 | 32 | 128 | mips_24kc | Discontinued 2016
+COMFAST | CF-E5  | WiFi AP | 650 | 16 | 64 | mips_24kc | Available 2019
+Compex | WPJ531 7A03 | Single Board Computer | 550 | 16 | 64 | mips_24kc | Available 2020
+D-Link | DGL-5500 A1 | WiFi Router | 720 | 16 | 128 | mips_24kc | Discontinued 2017
+D-Link | DHP-1565  | WiFi Router | 560 | 16 | 128 | mips_24kc | Discontinued 2018
+D-Link | DIR-510L A1 | Travel Router - Battery powered | 580 | 16 | 128 | mipsel_24kc | Discontinued 2017
+D-Link | DIR-825 C1 | WiFi Router | 560 | 16 | 128 | mips_24kc | Discontinued 2013
+D-Link | DIR-835 A1 | WiFi Router | 560 | 16 | 128 | mips_24kc | Discontinued 2016
+D-Link | DIR-860L B1 | WiFi Router | 880 | 16 | 128 | mipsel_24kc | Discontinued 2017
+D-Link | DWR-118 A1 | WiFi Router | 580 | 16 | 64 | mipsel_24kc | Discontinued
+D-Link | DWR-118 A2 | WiFi Router | 580 | 16 | 128 | mipsel_24kc | Discontinued
+D-Link | DWR-922 E2 | WiFi Router | 580 | 16 | 64 | mipsel_24kc | Discontinued
+D-Team | Newifi D2 (Newifi3)  | Router | 880 | 32 | 512 | mipsel_24kc | Available 2020
+Digineo | AC1200 Pro  | WiFi Router | 880 | 32 | 512 | mipsel_24kc | unknown 2018
+DomyWifi | DW33D  | unknown | 720 | 16,128NAND | 256 | mips_24kc | unknown 2018
+Dragino | MS14  | WiFi Router | 400 | 16 | 64 | mips_24kc | Available 2019
+Dragino | LPS8  | other | 400 | 16 | 64 | mips_24kc | Available 2021
+ELECOM | WRH-300CR  | Travel Router | 580 | 16 | 64 | mipsel_24kc | Available 2019
+Embedded Wireless | Balin  | Single Board Computer | 560 | 16 | 64 | mips_24kc | unknown 2018
+Embedded Wireless | Dorin Platform Rev 1.2 | WiFi Router | 400 | 16 | 64 | mips_24kc | unknown 2018
+EnGenius | EPG5000 v1.0.0 | WiFi Router | 720 | 16 | 256 | mips_24kc | Discontinued 2017
+EnGenius | ESR900 v1.00 | WiFi Router | 720 | 16 | 128 | mips_24kc | Discontinued
+EnGenius | ESR1750 v1.1.0 | WiFi Router | 720 | 16 | 256 | mips_24kc | Discontinued 2015
+Firefly | FireWRT  | WiFi Router | 880 | 16 | 512 | mipsel_24kc | Discontinued
+Gainstrong | MiniBox v1.0 | Travel Router | 400 | 16 | 64 | mips_24kc | unknown 2018
+Gainstrong | MiniBox v3.2 | WiFi Router | 550 | 16 | 128 | mips_24kc | Available 2019
+Gainstrong | Oolite v5.2 | other | 650 | 16 | 128 | mips_24kc | Available 2019
+Gainstrong | Oolite v1.0 | Single Board Computer | 400 | 16 | 64 | mips_24kc | unknown 2018
+GL.iNet | GL-MiFi  | Travel Router - Battery powered | 400 | 16 | 64 | mips_24kc | Available 2020
+GL.iNet | GL-M9331 Core (Domino Core)  | Single Board Computer | 400 | 16 | 64 | mips_24kc | Available 2020
+GL.iNet | Domino Pi  | Single Board Computer | 400 | 16 | 64 | mips_24kc | Discontinued 2017
+GL.iNet | GL-AR150  | Travel Router | 400 | 16 | 64 | mips_24kc | Available 2019
+GL.iNet | GL-AR300 v3 | WiFi Router | 560 | 16 | 128 | mips_24kc | Discontinued 2017
+GL.iNet | GL-AR300M-Lite v1 | Travel Router | 650 | 16 | 128 | mips_24kc | Available 2019
+GL.iNet | GL-AR300M v1.4.0 | WiFi Router | 650 | 16,128NAND | 128 | mips_24kc | Available 2020
+GL.iNet | GL-AR750  | Travel Router | 650 | 16 | 128 | mips_24kc | Available 2019
+GL.iNet | GL-AR750S v1 | Travel Router | 775 | 16,128NAND,microSDXC | 128 | mips_24kc | Available 2019
+GL.iNet | GL-MT300A v1.3 | Travel Router | 580 | 16 | 128 | mipsel_24kc | Discontinued
+GL.iNet | GL-MT300N v1 | Travel Router | 580 | 16 | 64 | mipsel_24kc | Discontinued
+GL.iNet | GL-MT300N v2 | WiFi Router | 580 | 16 | 128 | mipsel_24kc | Available 2020
+GL.iNet | GL-MT750  | WiFi Router | 580 | 16 | 128 | mipsel_24kc | Discontinued 2017
+GL.iNet | GL-USB150  | WiFi Router | 400 | 16 | 64 | mips_24kc | Discontinued 2022
+GL.iNet | GL-X750 (Spitz)  | WiFi Router | 650 | 16,microSDXC | 128 | mips_24kc | Available 2019
+GL.iNet | 6416A v1.0 | Travel Router | 400 | 16 | 64 | mips_24kc | Discontinued 2017
+Head Weblink | HDRM200  | WiFi Router | 580 | 16,microSD | 64 | mipsel_24kc | Available 2019
+HiWiFi/Gee | HC5661A  | WiFi Router | 580 | 16 | 128 | mipsel_24kc | Discontinued
+HiWiFi/Gee | HC5962  | WiFi Router | 880 | 128NAND | 256 | mipsel_24kc | Discontinued
+HiWiFi/Gee | HC6361  | WiFi Router | 400 | 16,4096NAND | 64 | mips_24kc | Discontinued
+I-O Data | WN-AC1600DGR  | WiFi Router | 720 | 16 | 128 | mips_24kc | Discontinued
+I-O Data | WN-AC1600DGR2  | WiFi Router | 720 | 16 | 128 | mips_24kc | Discontinued 2014
+I-O Data | WN-AC1167DGR  | WiFi Router | 720 | 16 | 128 | mips_24kc | Discontinued 2014
+I-O Data | WN-AC1600DGR3  | WiFi Router | 720 | 16 | 128 | mips_24kc | Available 2019
+I-O Data | WN-AG300DGR  | WiFi Router | 535 | 16 | 64 | mips_24kc | unknown 2018
+jjPlus | JWAP230  | WiFi Router | 720 | 16 | 128 | mips_24kc | Discontinued
+Kingston | MLW221  | Travel Router - Battery powered | 580 | 16 | 64 | mipsel_24kc | Available 2019
+Kingston | MLWG2  | Travel Router - Battery powered | 580 | 16 | 64 | mipsel_24kc | Discontinued 2016
+Lava | LR-25G001  | WiFi Router | 580 | 16 | 64 | mipsel_24kc | unknown 2018
+Lenovo | Newifi D1  | WiFi Router | 880 | 32,128 | 256 | mipsel_24kc | Discontinued
+Lenovo | Newifi mini Y1  | WiFi Router | 580 | 16 | 128 | mipsel_24kc | Discontinued
+Lenovo | Newifi Y1S  | WiFi Router | 580 | 16 | 256 | mipsel_24kc | Discontinued
+Librerouter | LibreRouter v1 | WiFi Router | 720 | 16 | 128 | mips_24kc | Available 2020
+MediaTek | LinkIt Smart 7688  | Single Board Computer | 580 | 32 | 128 | mipsel_24kc | Discontinued 2020
+Meraki | Z1  | WiFi Router | 560 | 128NAND | 128 | mips_24kc | Discontinued 2018
+Microduino | MicroWRT Core  | Single Board Computer | 580 | 16 | 64 | mipsel_24kc | unknown 2018
+MikroTik | RB751G-2HnD  | WiFi Router | 400 | 64NAND | 64 | mips_24kc | Discontinued
+MikroTik | RB411UAHR  | Single Board Computer | 680 | 64NAND | 64 | mips_24kc | Discontinued
+MikroTik | RB951G-2HnD  | Single Board Computer | 600 | 128NAND | 128 | mips_24kc | Available 2019
+MikroTik | RB951Ui-2HnD  | Single Board Computer | 600 | 128NAND | 128 | mips_24kc | Available 2019
+MikroTik | RB951Ui-2nD (hAP)  | WiFi Router | 650 | 16 | 64 | mips_24kc | Available 2019
+MikroTik | RB952Ui-5ac2nD (hAP ac lite)  | WiFi AP | 650 | 16 | 64 | mips_24kc | Available 2020
+MikroTik | RB962UiGS-5HacT2HnT (hAP ac)  | WiFi Router | 720 | 16 | 128 | mips_24kc | Available 2019
+MikroTik | RB2011  | Single Board Computer | 600 | ¿ | 128 | mips_24kc | Discontinued
+MikroTik | RB2011UAS-2HnD-IN  | Single Board Computer | 600 | 128NAND | 128 | mips_24kc | Available 2021
+MikroTik | RB2011UiAS-2HnD-IN r2 | WiFi Router | 600 | 128NAND | 128 | mips_24kc | Available 2019
+MikroTik | RBmAP-2nD (mAP)  | WiFi AP | 650 | 16 | 64 | mips_24kc | Available 2019
+MikroTik | RBmAPL-2nD (mAP lite) rev1,rev2 | WiFi AP | 650 | 16 | 64 | mips_24kc | Available 2019
+MikroTik | RBwAPR-2nD (wAP R)  | WiFi AP | 650 | 16 | 64 | mips_24kc | Available 2019
+MikroTik | RB912UAG-2HPnD  | Single Board Computer | 600 | 128NAND | 64 | mips_24kc | Available 2019
+MikroTik | RB912UAG-5HPnd  | Single Board Computer | 600 | 128NAND | 64 | mips_24kc | Available 2019
+MQMaker | WiTi Board v2.0 / 512MB | WiFi Router | 880 | 16 | 512 | mipsel_24kc | Available 2018
+MQMaker | WiTi Board v2.0 / 256MB | WiFi Router | 880 | 16 | 256 | mipsel_24kc | Discontinued 2019
+MTC | WR1201  | WiFi Router | 880 | 16,microSD | 128 | mipsel_24kc | Available 2019
+NETGEAR | WNDR3800  | WiFi Router | 680 | 16 | 128 | mips_24kc | Discontinued
+NETGEAR | WNDR3800 1CHNAS | WiFi Router | 680 | 16 | 128 | mips_24kc | Discontinued
+NETGEAR | WNDRMAC v1 | WiFi Router | 680 | 16 | 64 | mips_24kc | Discontinued
+NETGEAR | WNDRMAC v2 | WiFi Router | 680 | 16 | 128 | mips_24kc | Discontinued
+NETGEAR | R6120  | WiFi Router | 580 | 16 | 64 | mipsel_24kc | Available 2019
+NETGEAR | R6220  | WiFi Router | 880 | 128NAND | 128 | mipsel_24kc | Available 2020
+NETGEAR | R6100 v1 | WiFi AP | 560 | 128 | 128 | mips_24kc | Available 2021
+NETGEAR | R6350  | WiFi Router | 880 | 128NAND | 128 | mipsel_24kc | Available 2019
+NETGEAR | WNDR3700 v2 | WiFi Router | 680 | 16 | 64 | mips_24kc | Discontinued
+NETGEAR | WNDR3700 v4 | WiFi Router | 560 | 128NAND | 128 | mips_24kc | Discontinued
+NETGEAR | WNDR3700 v5 | WiFi Router | 880 | 16 | 128 | mipsel_24kc | Available 2019
+NETGEAR | WNDR4300 v1 | WiFi Router | 560 | 128NAND | 128 | mips_24kc | Discontinued
+NETGEAR | R6230  | WiFi Router | 880 | 128 | 128 | mipsel_24kc | Available 2019
+netis | WF2881  | WiFi Router | 880 | 128NAND | 128 | mipsel_24kc | Discontinued 2016
+netis | M1200AC  | WiFi Router | 880 | 128NAND | 128 | mipsel_24kc | Discontinued 2017
+Nexx | WT3020A  | Travel Router | 580 | 4 | 64 | mipsel_24kc | unknown 2018
+OMYlink | OMY-G1  | WiFi Router | 535 | 16 | 64 | mips_24kc | Discontinued
+Onion | Omega  | Single Board Computer | 400 | 16 | 64 | mips_24kc | Discontinued
+Onion | Omega2+  | Single Board Computer | 580 | 32,microSD | 128 | mipsel_24kc | Available 2019
+Onion | Omega2  | Single Board Computer | 580 | 16 | 64 | mipsel_24kc | Available 2019
+Open-Mesh | A60  | WiFi AP | 720 | 16 | 128 | mips_24kc | Discontinued 2019
+Oyewifi | OYE-0001  | WiFi Router | 580 | 16,SD | 128 | mipsel_24kc | Discontinued
+PHICOMM | K2T  | WiFi Router | 750 | 16 | 64 | mips_24kc | unknown 2018
+PISEN | WMM003N (Cloud Easy Power)  | Travel Router - Battery powered | 400 | 8,microSD | 64 | mips_24kc | Available 2021
+Qihoo hardware | C301  | WiFi Router | 560 | 32 | 128 | mips_24kc | Discontinued
+Qxwlan | E600GAC v2 | WiFi AP | 650 | 16 | 128 | mips_24kc | unknown 2018
+Qxwlan | E750G v8 16M | WiFi AP | 560 | 16 | 128 | mips_24kc | unknown 2018
+Qxwlan | E1700AC v2 | WiFi AP | 750 | 8,16 | 128 | mips_24kc | unknown 2018
+SamKnows | SK-WB8  | WiFi Router | 880 | 16 | 128 | mipsel_24kc | Available 2018
+Sanlinking | D240  | WiFi Router | 580 | 16 | 128 | mipsel_24kc | Discontinued
+Sitecom | WLR-8100 v1 001 | WiFi Router | 720 | 16 | 128 | mips_24kc | Discontinued
+Skylab | SKW92A EVB E16 | Single Board Computer | 580 | 16 | 64 | mipsel_24kc | unknown 2018
+Strong | 1200  | WiFi Router | 880 | 16 | 128 | mipsel_24kc | Available 2019
+Tama | W06  | WiFi Router | 575 | 16 | 64 | mipsel_24kc | unknown 2018
+TP-Link | Archer A7 v5 | WiFi Router | 750 | 16 | 128 | mips_24kc | Available 2019
+TP-Link | Archer C5 AC1200 v1 | WiFi Router | 720 | 16 | 128 | mips_24kc | Discontinued
+TP-Link | Archer C7 v2,v2.1 | WiFi Router | 720 | 16 | 128 | mips_24kc | Discontinued
+TP-Link | Archer C7 v3 | WiFi Router | 720 | 16 | 128 | mips_24kc | Discontinued
+TP-Link | Archer C7 v4 | WiFi Router | 775 | 16 | 128 | mips_24kc | Discontinued 2017
+TP-Link | Archer C7 v5 | WiFi Router | 750 | 16 | 128 | mips_24kc | Available 2019
+TP-Link | Archer C59 v1 | WiFi Router | 775 | 16 | 128 | mips_24kc | Discontinued 2017
+TP-Link | Archer C59 v2 | WiFi Router | 775 | 16 | 128 | mips_24kc | Discontinued
+TP-Link | TL-WR842N v3 | WiFi Router | 650 | 16 | 64 | mips_24kc | Discontinued
+TP-Link | TL-WR942N v1 | WiFi Router | 775 | 16 | 128 | mips_24kc | Discontinued
+TP-Link | TL-WR1043ND v4 | WiFi Router | 750 | 16 | 64 | mips_24kc | Discontinued
+TP-Link | VR200  | WiFi Router | 500 | 16 | 128 | mips_24kc | Available 2019
+TP-Link | VR200v  | WiFi Router | 500 | 16 | 128 | mips_24kc | Available 2019
+TRENDnet | TEW-823DRU v1.0R | WiFi Router | 720 | 16 | 256 | mips_24kc | Discontinued 2016
+Ubiquiti | airCube ISP  | WiFi AP | 650 | 16 | 64 | mips_24kc | Available 2019
+Ubiquiti | UniFi AP AC PRO  | WiFi Router | 775 | 16 | 128 | mips_24kc | Available 2018
+UniElec | U7628-01  | WiFi Router | 580 | 16,microSD | 128 | mipsel_24kc | Available 2019
+VoCore | VoCore2  | Single Board Computer | 580 | 16 | 128 | mipsel_24kc | Available 2018
+Western Digital | My Net N750  | WiFi Router | 560 | 16 | 128 | mips_24kc | Discontinued 2013
+Western Digital | My Net N600  | WiFi Router | 560 | 16 | 128 | mips_24kc | Discontinued
+WeVO | W2914NS v2 | WiFi Router | 880 | 16 | 128 | mipsel_24kc | Discontinued
+WeVO | 11AC NAS  | WiFi Router | 880 | 16 | 256 | mipsel_24kc | unknown 2019
+Widora | Widora-NEO 16M  | Single Board Computer | 580 | 16 | 128 | mipsel_24kc | Discontinued
+Widora | Widora-NEO 32M  | Single Board Computer | 580 | 32 | 128 | mipsel_24kc | Discontinued
+WIZnet | WizFi630S  | Single Board Computer | 580 | 32 | 128 | mipsel_24kc | Available 2019
+WRTnode | WRTnode 1 | WiFi Router | 580 | 16 | 64 | mipsel_24kc | Available 2018
+WRTnode | WRTnode 2P | Single Board Computer | 580 | 32 | 256 | mipsel_24kc | unknown 2018
+WRTnode | WRTnode 2R | Single Board Computer | 580 | 32 | 256 | mipsel_24kc | Available 2020
+Xiaomi | Mi Router 3 Pro  | WiFi Router | 880 | 256NAND | 512 | mipsel_24kc | Available 2019
+Xiaomi | Mi WiFi Mini v1 | WiFi Router | 580 | 16 | 128 | mipsel_24kc | Discontinued
+Xiaomi | MiWiFi 3G v1 | WiFi Router | 880 | 128NAND | 256 | mipsel_24kc | Discontinued
+Xiaomi | MiWiFi Nano  | WiFi Router | 575 | 16 | 64 | mipsel_24kc | Discontinued
+YouHua | WR1200JS  | WiFi Router | 880 | 16 | 128 | mipsel_24kc | Discontinued
+YOUKU | YK1, YK-L1  | WiFi Router | 580 | 32 | 128 | mipsel_24kc | Discontinued 2017
+YOUKU | YK-L2  | WiFi Router | 880 | 16 | 256 | mipsel_24kc | unknown 2019
+YunCore | SR3200  | WiFi Router | 775 | 16 | 128 | mips_24kc | unknown 2018
+YunCore | T830  | WiFi Router | 650 | 16 | 128 | mips_24kc | unknown 2018
+ZBT | WE826-E  | WiFi Router | 580 | 32 | 128 | mipsel_24kc | unknown 2019
+ZBT | WE826 B0 16M | WiFi Router | 580 | 16,SD | 128 | mipsel_24kc | Available 2019
+ZBT | WE826 B0 32M | WiFi Router | 580 | 32 | 128 | mipsel_24kc | Available 2021
+ZBT | WE826 T 16M | WiFi Router | 580 | 16,SD | 128 | mipsel_24kc | Available 2019
+ZBT | WE826 T 32M | WiFi Router | 580 | 32 | 128 | mipsel_24kc | Available 2021
+ZBT | WE1026-5G  | WiFi Router | 580 | 16,microSD | 64 | mipsel_24kc | Available 2019
+ZBT | WE1326  | WiFi Router | 880 | 16 | 512 | mipsel_24kc | Available 2019
+ZBT | WE1526  | WiFi Router | 650 | 16 | 128 | mips_24kc | Available 2019
+ZBT | WE3526  | WiFi AP | 880 | 16 | 512 | mipsel_24kc | Available 2019
+ZBT | WG2626 v03 | WiFi Router | 880 | 16 | 512 | mipsel_24kc | Available 2019
+ZBT | WG3526 16M | WiFi Router | 880 | 16 | 512 | mipsel_24kc | Available 2020
+ZBT | WG3526 32M | WiFi Router | 880 | 32 | 512 | mipsel_24kc | Available 2019
+ZBT | ZBT-WD323  | WiFi Router | 560 | 16 | 128 | mips_24kc | Available 2019
+ZTE | Q7  | Travel Router - Battery powered | 580 | 8,SD | 64 | mipsel_24kc | Discontinued 2020
+ZyXEL | Keenetic Extra II  | WiFi Router | 580 | 32 | 128 | mipsel_24kc | unknown 2018
+ZyXEL | Keenetic 4G III rev. B | WiFi Router | 575 | 16 | 64 | mipsel_24kc | Discontinued
+ZyXEL | EMG2926-Q10A 1.00,A02,A03 | WiFi Router | 720 | 16,128NAND | 256 | mips_24kc | Available 2019
+ZyXEL | Keenetic Viva rev. B | WiFi Router | 580 | 16 | 128 | mipsel_24kc | Discontinued 2020
+ZyXEL | NBG6616 A00 | WiFi Router | 720 | 16 | 128 | mips_24kc | Discontinued 2020
+ZyXEL | NBG6716 A01 | WiFi Router | 720 | 16,256 | 256 | mips_24kc | Discontinued 2016
+ZyXEL | P-2812HNU-F1  | WiFi Router | 500 | 128NAND | 128 | mips_24kc | Discontinued

+ 64 - 0
files/common/etc/20-sd-universal

@@ -0,0 +1,64 @@
+#!/bin/bash
+# this script fix the nano mechanism of usb\30-sd -> block\20-sd - by DSR!
+
+device=`basename $DEVPATH`
+devNum=$(echo $device | awk -F "" '{print $4}')
+
+[[ $ACTION == "add" ]] && {
+    mkdir -p /dev/sdcard
+    mkdir -p /sd
+
+    [[ $devNum == "" ]] && {
+        rm -rf /dev/sdcard/sd
+        ln -s /dev/$device /dev/sdcard/sd
+    } || {
+        rm -rf /dev/sdcard/sd$devNum
+        ln -s /dev/$device /dev/sdcard/sd$devNum
+
+        [[ $devNum == "1" ]] && {
+            logger "== Add pendrive as SD"
+            umount /sd
+            mount /dev/sdcard/sd$devNum /sd && {
+                [[ -e "/sd/etc" ]] || {
+                    sleep 5
+                    ln -s /etc/ /sd/etc
+                }
+            }
+
+            if [[ -e "/sd/modules/" ]]; then
+                logger "== Link modules in /sd/modules/"
+                for module in `ls /sd/modules/`; do
+                    if [[ ! -d "/pineapple/modules/$module" ]]; then
+                        ln -s /sd/modules/$module /pineapple/modules/$module
+                    fi
+                done
+            fi
+
+            # autoinstall python in universal flavor
+            if [[ ! -d "/usr/lib/python2.7" && ! -d "/sd/usr/lib/python2.7" ]]; then
+                /usr/bin/wpc-tools missing_packages
+            fi
+        }
+
+        [[ $devNum == "2" ]] && {
+            logger "== Add swap"
+            swapoff /dev/sdcard/sd$devNum
+            swapon /dev/sdcard/sd$devNum
+        }
+    }
+}
+
+[[ $ACTION == "remove" ]] && {
+    [[ $devNum == "" ]] && {
+        umount /sd
+        rm -rf /dev/sdcard/sd
+    }
+
+    [[ $devNum == "1" ]] && {
+        rm -rf /dev/sdcard/sd$devNum
+    }
+
+    [[ $devNum == "2" ]] && {
+        swapoff /dev/sdcard/sd$devNum
+    }
+}

+ 12 - 0
files/common/etc/30-fix_wifi

@@ -0,0 +1,12 @@
+#!/bin/bash
+
+[[ $ACTION == "remove" ]] && exit
+[[ $DEVTYPE == "usb_interface" ]] || exit
+
+wifi config >> /etc/config/wireless
+WIFIDEV=$(uci show wireless | grep "${DEVPATH:9}" | awk -F'.' '{print $2}')
+
+[[ ! -z $WIFIDEV ]] && {
+    wifi reload $WIFIDEV
+    wifi up $WIFIDEV
+}

+ 94 - 0
files/common/etc/90-firewall.sh

@@ -0,0 +1,94 @@
+# -- Setup firewall configuration
+uci set firewall.@defaults[0].syn_flood=1
+uci set firewall.@defaults[0].input=ACCEPT
+uci set firewall.@defaults[0].output=ACCEPT
+uci set firewall.@defaults[0].forward=ACCEPT
+
+uci add firewall zone
+uci set firewall.@zone[-1]=zone
+uci set firewall.@zone[-1].name=usb
+uci add_list firewall.@zone[-1].network='usb'
+uci set firewall.@zone[-1].input=ACCEPT
+uci set firewall.@zone[-1].output=ACCEPT
+uci set firewall.@zone[-1].forward=ACCEPT
+uci set firewall.@zone[-1].masq=1
+uci set firewall.@zone[-1].mtu_fix=1
+
+uci add firewall forwarding
+uci set firewall.@forwarding[-1].src=lan
+uci set firewall.@forwarding[-1].dest=usb
+
+uci add firewall forwarding
+uci set firewall.@forwarding[-1].src=usb
+uci set firewall.@forwarding[-1].dest=lan
+
+uci add firewall zone
+uci set firewall.@zone[-1]=zone
+uci set firewall.@zone[-1].name=wwan
+uci add_list firewall.@zone[-1].network=wwan
+uci add_list firewall.@zone[-1].network=wwan6
+uci set firewall.@zone[-1].input=ACCEPT
+uci set firewall.@zone[-1].output=ACCEPT
+uci set firewall.@zone[-1].forward=ACCEPT
+uci set firewall.@zone[-1].masq=1
+uci set firewall.@zone[-1].mtu_fix=1
+
+uci add firewall forwarding
+uci set firewall.@forwarding[-1].src=lan
+uci set firewall.@forwarding[-1].dest=wwan
+
+uci add firewall forwarding
+uci set firewall.@forwarding[-1].src=wwan
+uci set firewall.@forwarding[-1].dest=lan
+
+uci add firewall zone
+uci set firewall.@zone[-1].name=wan
+uci add_list firewall.@zone[-1].network='wan'
+uci add_list firewall.@zone[-1].network='wan6'
+uci set firewall.@zone[-1].input=ACCEPT
+uci set firewall.@zone[-1].output=ACCEPT
+uci set firewall.@zone[-1].forward=ACCEPT
+uci set firewall.@zone[-1].masq=1
+uci set firewall.@zone[-1].mtu_fix=1
+
+uci add firewall forwarding
+uci set firewall.@forwarding[-1].src=lan
+uci set firewall.@forwarding[-1].dest=wan
+
+uci add firewall forwarding
+uci set firewall.@forwarding[-1].src=wan
+uci set firewall.@forwarding[-1].dest=lan
+
+uci add firewall allowssh
+uci set firewall.allowssh=rule
+uci set firewall.allowssh.name='Allow-SSH'
+uci set firewall.allowssh.src='wan'
+uci set firewall.allowssh.proto='tcp'
+uci set firewall.allowssh.dest_port='22'
+uci set firewall.allowssh.target='ACCEPT'
+uci set firewall.allowssh.family='ipv4'
+uci set firewall.allowssh.enabled='0'
+
+uci add firewall allowui
+uci set firewall.allowui=rule
+uci set firewall.allowui.name='Allow-WEB'
+uci set firewall.allowui.src='wan'
+uci set firewall.allowui.proto='tcp'
+uci set firewall.allowui.dest_port='1471'
+uci set firewall.allowui.target='ACCEPT'
+uci set firewall.allowui.family='ipv4'
+uci set firewall.allowui.enabled='0'
+
+uci add firewall allowws
+uci set firewall.allowws=rule
+uci set firewall.allowws.name='Allow-WEB-WS'
+uci set firewall.allowws.src='wan'
+uci set firewall.allowws.proto='tcp'
+uci set firewall.allowws.dest_port='1337'
+uci set firewall.allowws.target='ACCEPT'
+uci set firewall.allowws.family='ipv4'
+uci set firewall.allowws.enabled='1'
+
+uci commit firewall
+
+exit 0

+ 8 - 0
files/common/etc/92-system.sh

@@ -0,0 +1,8 @@
+# -- Setup system configuration
+
+# Change the hostname
+uci set system.@system[0].hostname=Pineapple
+uci commit system
+echo $(uci get system.@system[0].hostname) > /proc/sys/kernel/hostname
+
+exit 0

+ 24 - 0
files/common/etc/95-network.sh

@@ -0,0 +1,24 @@
+# -- Set up Networking configuration
+uci set network.lan.type='bridge'
+uci set network.lan.proto='static'
+uci set network.lan.ipaddr='172.16.42.1'
+uci set network.lan.netmask='255.255.255.0'
+uci set network.lan.gateway='172.16.42.42'
+uci set network.lan.dns='8.8.8.8, 8.8.4.4'
+
+uci set network.usb=interface
+uci set network.usb.ifname='usb0'
+uci set network.usb.proto='dhcp'
+uci set network.usb.dns='8.8.8.8, 8.8.4.4'
+
+uci set network.wwan=interface
+uci set network.wwan.proto='dhcp'
+uci set network.wwan.dns='8.8.8.8, 8.8.4.4'
+
+uci set network.wan.proto='dhcp'
+uci set network.wan.dns='8.8.8.8, 8.8.4.4'
+
+uci set network.wan6.proto='dhcpv6'
+uci commit network
+
+exit 0

+ 51 - 0
files/common/etc/97-pineapple.sh

@@ -0,0 +1,51 @@
+# Make SSH banner have the correct version and device
+version=$(cat /pineapple/pineapple_version | head -c 5)
+eval "sed -i s/VERSION/$version/g /etc/banner"
+
+# Configure PATH with SD card directories
+echo "export PATH=/usr/bin/pineapple:/bin:/sbin:/usr/bin:/usr/sbin:/sd/bin:/sd/sbin:/sd/usr/sbin:/sd/usr/bin" >> /etc/profile
+echo "export LD_LIBRARY_PATH=/lib:/usr/lib:/sd/lib:/sd/usr/lib" >> /etc/profile 
+
+# Touch known hosts
+mkdir -p /root/.ssh/
+touch /root/.ssh/known_hosts
+
+# "Temporarily" soft-link libpcap.so.1 to libpcap.so.1.3
+ln -s /usr/lib/libpcap.so.1 /usr/lib/libpcap.so.1.3
+
+# Disable AutoSSH
+/etc/init.d/autossh stop
+/etc/init.d/autossh disable
+
+# Correct opkg sources
+sed -i "s/src\/gz openwrt_freifunk/#src\/gz openwrt_freifunk/" /etc/opkg/distfeeds.conf
+sed -i "s/src\/gz openwrt_luci/#src\/gz openwrt_luci/" /etc/opkg/distfeeds.conf
+sed -i "s/src\/gz openwrt_telephony/#src\/gz openwrt_telephon/" /etc/opkg/distfeeds.conf
+
+# Get valid led value
+PINE_LED=""
+LED_TYPES="wps status system wan"
+LED_LIST=$(ls "/sys/class/leds/")
+for LED_TYPE in $LED_TYPES; do
+    for LED_NAME in $LED_LIST; do
+        if expr match "$LED_NAME" "\(.*:$LED_TYPE\)"; then
+            PINE_LED="$LED_NAME"
+            break
+        fi
+    done
+
+    if [[ $PINE_LED != "" ]]; then
+        break
+    fi
+done
+
+if [[ $PINE_LED == "" && $LED_LIST != "" ]]; then
+    PINE_LED=$(ls "/sys/class/leds/" | tail -1)
+fi
+
+if [[ $PINE_LED != "" ]]; then
+    sed -i "s/wifi-pineapple-nano:blue:system/$PINE_LED/" /sbin/led
+    echo 255 > "/sys/class/leds/$PINE_LED/brightness"
+fi
+
+exit 0

+ 23 - 0
files/common/etc/banner

@@ -0,0 +1,23 @@
+                                               .NN,                            
+                                    .cxxdl'    xMMO    'cdxxl'                 
+                                      .c0WMNk;,NMMW:,xXMMKo.                   
+                                      ...:KMMMWMMMMWMMMXc...           .       
+                         ,        .l0NMMMNXMMMMMMMMMMMMXNMMMWKl'      xWd      
+                       ,0Wd         .':xNMMMMMMMMMMMMMMMMNkc'.        ;KM0'    
+                      lWMo            .;dNMMMMMMMMMMMMMMWx:.      .l.   dMWc   
+                     :WWo   oNd   .;xKWMMMMMMMMMMMMMMMMMMMMWXx:.  dWX:   dMW;  
+                    ,NWo   oMW:   .. ..,lOXWMMMMMMMMMMWN0o;.. ..   cWMl   dMN' 
+                   .XMx   oWN;   lc     .loooolcooclooool.    cXl   oMWc   kMK.
+                   oMW'  ,WMl   cMW:   lWMW0d:;cdd:;:o0WMWl   lMW:   OMW'  ,WMl
+                   0M0   xMX.  .XMd   .lo:.,dXMMMMMMXd,.:ol.   kMK.  'NMd   KMO
+                   NMd   KMk   lMN.  .;:xOxollccddcclloxOx:;.  'WM:   OM0   xMX
+                   WMo  .XMx   dMK   oNMMMMWOc;;ol;;cOWMMMMNo  .XMl   kMK   dMN
+                   NMx   0MO   :Kd. .lllcl;.:0WMMMMW0:.;lclll. .xK;   0MO   kMX
+ __          ___ ______ _   _____ _.:W0;,oxl:::oOOo:::lxo,;0W:   _   .ONo   KMk
+ \ \        / (_|  ____(_) |  __ (_);cKMMMMWk:.;,.;kWMMMMKc;.   | |        .OX:
+  \ \  /\  / / _| |__   _  | |__) _ _ __   ___  __ _ _ __  _ __ | | ___  DEVICE
+   \ \/  \/ / | |  __| | | |  ___| | '_ \ / _ \/ _` | '_ \| '_ \| |/ _ \ VERSION 
+    \  /\  /  | | |    | | | |   | | | | |  __| (_| | |_) | |_) | |  __/ by DSR!
+     \/  \/   |_|_|    |_| |_|   |_|_| |_|\___|\__,_| .__/| .__/|_|\___|       
+ web: github.com/xchwarze/wifi-pineapple-cloner     | |   | |                  
+ ------------------------------                     |_|   |_|                  

+ 5 - 0
files/common/etc/shadow

@@ -0,0 +1,5 @@
+root:$1$3DBtk82B$6EPlkFc9GQrtDwmzKsUn31:18739:0:99999:7:::
+daemon:*:0:0:99999:7:::
+ftp:*:0:0:99999:7:::
+network:*:0:0:99999:7:::
+nobody:*:0:0:99999:7:::

+ 14 - 0
files/common/etc/wpc-tools

@@ -0,0 +1,14 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2022 DSR!
+
+START=99
+
+start() {
+    wpc-tools correct_sd_mount
+    wpc-tools missing_packages
+    wpc-tools handle_lost_phys
+}
+
+boot() {
+    start
+}

+ 84 - 0
files/common/etc/wps

@@ -0,0 +1,84 @@
+#!/bin/sh
+
+wps_catch_credentials() {
+	local iface ifaces ifc ifname ssid encryption key radio radios
+	local found=0
+
+	. /usr/share/libubox/jshn.sh
+	ubus -S -t 30 listen wps_credentials | while read creds; do
+		json_init
+		json_load "$creds"
+		json_select wps_credentials || continue
+		json_get_vars ifname ssid key encryption
+		local ifcname="$ifname"
+		json_init
+		json_load "$(ubus -S call network.wireless status)"
+		json_get_keys radios
+		for radio in $radios; do
+			json_select $radio
+			json_select interfaces
+			json_get_keys ifaces
+			for ifc in $ifaces; do
+				json_select $ifc
+				json_get_vars ifname
+				[ "$ifname" = "$ifcname" ] && {
+					ubus -S call uci set "{\"config\":\"wireless\", \"type\":\"wifi-iface\",		\
+								\"match\": { \"device\": \"$radio\", \"encryption\": \"wps\" },	\
+								\"values\": { \"encryption\": \"$encryption\", 			\
+										\"ssid\": \"$ssid\", 				\
+										\"key\": \"$key\" } }"
+					ubus -S call uci commit '{"config": "wireless"}'
+					ubus -S call uci apply
+				}
+				json_select ..
+			done
+			json_select ..
+			json_select ..
+		done
+	done
+}
+
+# from mk6 reset script 
+#########################
+if [ -f "/etc/pineapple/setupRequired" ]; then
+    if [ -f /etc/pineapple/init ]; then
+        exit
+    fi
+
+    if [ ! -f /tmp/button_setup ]; then
+        if [ "$SEEN" -lt 2 ]; then
+            logger "First Setup: Disable WiFi"
+            wifi down
+            ifconfig wlan0 down && ifconfig wlan0-1 down
+            /sbin/led blue on
+        else
+            logger "First Setup: Keep WiFi On"
+        fi
+        touch /tmp/button_setup
+    fi
+    exit
+fi
+#########################
+
+if [ "$ACTION" = "pressed" -a "$BUTTON" = "wps" ]; then
+	wps_done=0
+	ubusobjs="$( ubus -S list hostapd.* )"
+	for ubusobj in $ubusobjs; do
+		ubus -S call $ubusobj wps_start && wps_done=1
+	done
+	[ $wps_done = 0 ] || return 0
+	wps_done=0
+	ubusobjs="$( ubus -S list wpa_supplicant.* )"
+	for ubusobj in $ubusobjs; do
+		ifname="$(echo $ubusobj | cut -d'.' -f2 )"
+		multi_ap=""
+		if [ -e "/var/run/wpa_supplicant-${ifname}.conf.is_multiap" ]; then
+			ubus -S call $ubusobj wps_start '{ "multi_ap": true }' && wps_done=1
+		else
+			ubus -S call $ubusobj wps_start && wps_done=1
+		fi
+	done
+	[ $wps_done = 0 ] || wps_catch_credentials &
+fi
+
+return 0

+ 5 - 0
files/common/lib/pineapple.keep

@@ -0,0 +1,5 @@
+/etc/pineape
+/etc/pineapple
+/pineapple/css
+/pineapple/img/logo.png
+/pineapple/img/throbber.gif

+ 20 - 0
files/common/pineapple/config.php.nano

@@ -0,0 +1,20 @@
+<?php
+
+class DeviceConfig
+{
+    // third party modules can change the options based on this
+    // the allowed values are: "nano" or "tetra"
+    const DEVICE_TYPE = 'nano';
+
+    const USE_INTERNAL_STORAGE = false;
+
+    const USE_USB_STORAGE = true;
+
+    const SHOW_FIREWALL_CONFIG = false;
+
+    // third party modules do not have this flag implemented
+    const SHOW_SCAN_TYPE = false;
+
+    // hide wlan0 in getClientInterfaces() enumeration
+    const HIDE_WLAN0_CLIENT = true;
+}

+ 20 - 0
files/common/pineapple/config.php.tetra

@@ -0,0 +1,20 @@
+<?php
+
+class DeviceConfig
+{
+    // third party modules can change the options based on this
+    // the allowed values are: "nano" or "tetra"
+    const DEVICE_TYPE = 'tetra';
+
+    const USE_INTERNAL_STORAGE = true;
+
+    const USE_USB_STORAGE = true;
+
+    const SHOW_FIREWALL_CONFIG = true;
+
+    // third party modules do not have this flag implemented
+    const SHOW_SCAN_TYPE = true;
+
+    // hide wlan0 in getClientInterfaces() enumeration
+    const HIDE_WLAN0_CLIENT = true;
+}

BIN
files/common/pineapple/favicon-16x16.png


BIN
files/common/pineapple/favicon-32x32.png


BIN
files/common/pineapple/favicon.ico


+ 54 - 0
files/common/sbin/led

@@ -0,0 +1,54 @@
+#!/bin/sh
+
+# Usage: led <color|reset> [on|off]
+
+usage() {
+    echo "Usage: led <color|reset> [on|off]"
+    echo " "
+    echo "Available colors are: BLUE"
+    exit 1
+}
+
+resetLEDs() {
+    /etc/init.d/led restart
+}
+
+setLED() {
+    led=$1
+    state=$2
+    case "$led" in
+        blue|BLUE|all|ALL)
+            echo "$state" > /sys/class/leds/wifi-pineapple-nano:blue:system/brightness
+            ;;
+        *)
+            usage
+            ;;
+    esac
+}
+
+color=$(echo "$1" | tr '[:upper:]' '[:lower:]')
+mode=$(echo "$2" | tr '[:upper:]' '[:lower:]')
+
+case "$color" in
+    reset)
+        resetLEDs
+        ;;
+    blue|all)
+        case "$mode" in
+            on)
+                setLED $color 255
+                ;;
+            off)
+                setLED $color 0
+                ;;
+            *)
+                usage
+                ;;
+        esac
+        ;;
+    *)
+        usage
+        ;;
+esac
+
+echo "Done."

+ 1533 - 0
files/common/usr/airmon-ng

@@ -0,0 +1,1533 @@
+#!/bin/sh
+DEBUG="0"
+VERBOSE="0"
+ELITE="0"
+USERID=""
+IFACE=""
+checkvm_status=""
+MAC80211=0
+IW_SOURCE="https://mirrors.edge.kernel.org/pub/software/network/iw/iw-5.0.1.tar.gz"
+IW_ERROR=""
+if [ ! -d /sys/ ]; then
+	printf "CONFIG_SYSFS is disabled in your kernel, this program will almost certainly not work.\n"
+fi
+
+if [ "${1}" = "--elite" ]; then
+	shift
+	ELITE="1"
+fi
+
+if [ "${1}" = "--verbose" ]; then
+	shift
+	VERBOSE="1"
+fi
+
+if [ "${1}" = "--debug" ]; then
+	shift
+	DEBUG="1"
+	VERBOSE="1"
+fi
+
+#yes, I know this is in here twice
+if [ "${1}" = "--elite" ]; then
+	shift
+	ELITE="1"
+fi
+
+
+if [ -n "${3}" ];then
+	if [ "${3}" -gt 0 ] > /dev/null 2>&1; then
+		CH="${3}"
+	else
+		printf "\nYou have entered an invalid channel \"${3}\" which will be ignored\n"
+		CH=3
+	fi
+else
+	CH=10
+fi
+
+#TODO LIST
+
+#cleanup getDriver()
+#fix to not assume wifi drivers are modules
+#rewrite to not have two devices at any one time
+
+if [ -n "$(command -v id 2> /dev/null)" ]; then
+	USERID="$(id -u 2> /dev/null)"
+fi
+
+if [ -z "${USERID}" ] && [ -n "$(id -ru)" ]; then
+	USERID="$(id -ru)"
+fi
+
+if [ -n "${USERID}" ] && [ "${USERID}" != "0" ]; then
+	printf "Run it as root\n" ; exit 1;
+elif [ -z "${USERID}" ]; then
+	printf "Unable to determine user id, permission errors may occur.\n"
+fi
+
+#check for all needed binaries
+if [ ! -x "$(command -v uname 2>&1)" ]; then
+	printf "How in the world do you not have uname installed?\n"
+	printf "Please select a linux distro which has at least basic functionality (or install uname).\n"
+	exit 1
+else
+        OS=$(uname -s)
+	#Recognized values are Linux and Darwin
+fi
+
+if [ ! -x "$(command -v ip 2>&1)" ] && [ ! -x "$(command -v ifconfig 2>&1)" ]; then
+	printf "You have neither ip (iproute2) nor ifconfig installed.\n"
+	printf "Please install one of them from your distro's package manager.\n"
+	exit 1
+fi
+
+if [ ! -x "$(command -v iw 2>&1)" ]; then
+	printf "You don't have iw installed, please install it from your distro's package manager.\n"
+	printf "If your distro doesn't have a recent version you can download it from this link:\n"
+	printf "${IW_SOURCE}\n"
+	exit 1
+fi
+
+if [ ! -x "$(command -v ethtool 2>&1)" ]; then
+	printf "Please install the ethtool package for your distro.\n"
+	exit 1
+fi
+
+if [ -d /sys/bus/usb ]; then
+	if [ ! -x "$(command -v lsusb 2>&1)" ]; then
+		printf "Please install lsusb from your distro's package manager.\n"
+		exit 1
+	else
+		LSUSB=1
+	fi
+else
+	LSUSB=0
+fi
+
+LSPCI=0
+# if [ -d /sys/bus/pci ] || [ -d /sys/bus/pci_express ] || [ -d /proc/bus/pci ]; then
+# 	PCI_DEVICES=0
+# 	if [ -d /sys/bus/pci/devices ] && [ "$(ls -1 /sys/bus/pci/devices 2>/dev/null | wc -l)" != '0' ]; then
+# 		PCI_DEVICES=1
+# 	elif [ -r /proc/bus/pci/devices ] && [ -n "$(cat /proc/bus/pci/devices 2>/dev/null)" ]; then
+# 		PCI_DEVICES=1
+# 	elif [ -d /sys/bus/pci_express/devices ] && [ -n "$(ls -1 /sys/bus/pci_express/devices 2>/dev/null | wc -l)" != '0' ]; then
+# 		PCI_DEVICES=1
+# 	fi
+
+# 	if [ ${PCI_DEVICES} -eq 0 ]; then
+# 		LSPCI=0
+# 	elif [ ! -x "$(command -v lspci 2>&1)" ]; then
+# 		printf "Please install lspci from your distro's package manager.\n"
+# 		exit 1
+# 	else
+# 		LSPCI=1
+# 	fi
+# else
+# 	LSPCI=0
+# fi
+
+if [ -f /proc/modules ] || [ -d /sys/module ]; then
+	if [ ! -x "$(command -v modprobe 2>&1)" ]; then
+		printf "Your kernel has module support but you don't have modprobe installed.\n"
+		printf "It is highly recommended to install modprobe (typically from kmod).\n"
+		MODPROBE=0
+	else
+		MODPROBE=1
+	fi
+	if [ ! -x "$(command -v modinfo 2>&1)" ]; then
+		printf "Your kernel has module support but you don't have modinfo installed.\n"
+		printf "It is highly recommended to install modinfo (typically from kmod).\n"
+		printf "Warning: driver detection without modinfo may yield inaccurate results.\n"
+		MODINFO=0
+	else
+		MODINFO=1
+	fi
+else
+	MODINFO=0
+fi
+
+if [ -c /dev/rfkill ]; then
+	if [ ! -x "$(command -v rfkill 2>&1)" ];then
+		printf "Your kernel supports rfkill but you don't have rfkill installed.\n"
+		printf "To ensure devices are unblocked you must install rfkill.\n"
+		RFKILL=0
+	else
+		RFKILL=1
+	fi
+else
+	RFKILL=0
+fi
+
+if [ ! -x "$(command -v awk 2>&1)" ]; then
+	printf "How in the world do you not have awk installed?\n"
+	printf "Please select a linux distro which has at least basic functionality (or install awk).\n"
+	exit 1
+fi
+
+if [ ! -x "$(command -v grep 2>&1)" ]; then
+	printf "How in the world do you not have grep installed?\n"
+	printf "Please select a linux distro which has at least basic functionality (or install grep).\n"
+	exit 1
+fi
+#done checking for binaries
+
+usage() {
+	printf "usage: $(basename $0) <start|stop|check> <interface> [channel or frequency]\n\n"
+	exit 0
+}
+
+handleLostPhys() {
+	MISSING_INTERFACE=""
+        if [ -d /sys/class/ieee80211 ]; then
+		for i in $(ls /sys/class/ieee80211/); do
+			if [ ! -d /sys/class/ieee80211/${i}/device/net ]; then
+				MISSING_INTERFACE="${i}"
+				printf "\nFound ${MISSING_INTERFACE} with no interfaces assigned, would you like to assign one to it? [y/n] "
+				yesorno
+				retcode=$?
+	               		if [ "${retcode}" = "1" ]; then
+					printf "PHY ${MISSING_INTERFACE} will remain lost.\n"
+				elif [ "${retcode}" = "0" ]; then
+					PHYDEV=${MISSING_INTERFACE}
+					findFreeInterface monitor
+	               		fi
+			fi
+		done
+	fi
+				#add some spacing so this doesn't make the display hard to read
+				printf "\n"
+}
+
+findFreeInterface() {
+	if [ -z "${1}" ]; then
+		printf "findFreeInterface needs a target mode.\n"
+		exit 1
+	fi
+	if [ "${1}" != "monitor" ] && [ "${1}" != "station" ]; then
+		printf "findFreeInterface only supports monitor and station for target mode.\n"
+		exit 1
+	fi
+	target_mode="${1}"
+	if [ "$target_mode" = "monitor" ]; then
+		target_suffix="mon"
+		target_type="803"
+	else
+		target_suffix=""
+		target_type="1"
+	fi
+	for i in $(seq 0 100); do
+		if [ "$i" = "100" ]; then
+			printf "\n\tUnable to find a free name between wlan0 and wlan99, you are on your own from here.\n"
+			return 1
+		fi
+		if [ "$DEBUG" = "1" ]; then
+			printf "\nChecking candidate wlan${i}\n"
+		fi
+		if [ ! -e /sys/class/net/wlan${i} ]; then
+			if [ "$DEBUG" = "1" ]; then
+				printf "\nCandidate wlan${i} is not in use\n"
+			fi
+			if [ ! -e /sys/class/net/wlan${i}mon ]; then
+				if [ "$DEBUG" = "1" ]; then
+					printf "\nCandidate wlan${i} and wlan${i}mon are both clear, creating wlan${i}${target_suffix}\n"
+				fi
+				IW_ERROR="$(iw phy ${PHYDEV} interface add wlan${i}${target_suffix} type ${target_mode} 2>&1)"
+				if [ -z "${IW_ERROR}" ]; then
+					if [ -d /sys/class/ieee80211/${PHYDEV}/device/net ]; then
+						for j in $(ls /sys/class/ieee80211/${PHYDEV}/device/net/); do
+							if [ "$(cat /sys/class/ieee80211/${PHYDEV}/device/net/${j}/type)" = "${target_type}" ]; then
+								#here is where we catch udev renaming our interface
+								k=${j#wlan}
+								i=${k%mon}
+							fi
+						done
+					else
+						printf "Unable to create wlan${i}${target_suffix} and no error received.\n"
+						return 1
+					fi
+					printf "\n\t\t(mac80211 ${target_mode} mode vif enabled on [${PHYDEV}]wlan${i}${target_suffix}\n"
+					unset IW_ERROR
+					break
+				else
+					printf "\n\n ERROR adding ${target_mode} mode interface: ${IW_ERROR}\n"
+					break
+				fi
+			else
+				if [ "$DEBUG" = "1" ]; then
+					printf "\nCandidate wlan${i} does not exist, but wlan${i}mon does, skipping...\n"
+				fi
+			fi
+		else
+			if [ "$DEBUG" = "1" ]; then
+				printf "\nCandidate wlan${i} is in use already.\n"
+			fi
+		fi
+	done
+}
+
+rfkill_check() {
+	#take phy and check blocks
+	if [ "${RFKILL}" = 0 ]; then
+		#immediately return if rfkill isn't supported
+		return 0
+	fi
+	if [ -z "${1}" ]; then
+		printf "Fatal, rfkill_check requires a phy to be passed in\n"
+		exit 1
+	fi
+	#first we have to find the rfkill index
+	#this is available as /sys/class/net/wlan0/phy80211/rfkill## but that's a bit difficult to parse
+	index="$(rfkill list | grep "${1}:" | awk -F: '{print $1}')"
+	if [ -z "$index" ]; then
+		return 187
+	fi
+	rfkill_status="$(rfkill list ${index} 2>&1)"
+	if [ $? != 0 ]; then
+		printf "rfkill error: ${rfkill_status}\n"
+		return 187
+	elif [ -z "${rfkill_status}" ]; then
+		printf "rfkill had no output, something went wrong.\n"
+		exit 1
+	else
+		soft=$(printf "${rfkill_status}" | grep -i soft | awk '{print $3}')
+		hard=$(printf "${rfkill_status}" | grep -i hard | awk '{print $3}')
+		if [ "${soft}" = "yes" ] && [ "${hard}" = "no" ]; then
+			return 1
+		elif [ "${soft}" = "no" ] && [ "${hard}" = "yes" ]; then
+			return 2
+		elif [ "${soft}" = "yes" ] && [ "${hard}" = "yes" ]; then
+			return 3
+		fi
+	fi
+	return 0
+}
+
+rfkill_unblock() {
+	#attempt unblock and CHECK SUCCESS
+	if [ "${RFKILL}" = 0 ]; then
+		#immediately return if rfkill isn't supported
+		return 0
+	fi
+	rfkill_status="$(rfkill unblock ${1#phy} 2>&1)"
+	if [ $? != 0 ]; then
+		rfkill_status="$(rfkill unblock $index 2>&1)"
+		if [ $? != 0 ]; then
+			if [ `echo "$blah" | grep "Usage" | wc -l` -eq 1 ]; then
+				printf "Missing parameters in rfkill! Report this"
+			else
+				printf "rfkill error: ${rfkill_status}\n"
+			fi
+			printf "Unable to unblock.\n"
+			return 1
+		fi
+	fi
+
+	sleep 1
+	return 0
+}
+
+setLink() {
+	if [ -x "$(command -v ip 2>&1)" ]; then
+		ip link set dev ${1} ${2} > /dev/null 2>&1 || printf "\nFailed to set ${1} ${2} using ip\n"
+	elif [ -x "$(command -v ifconfig 2>&1)" ]; then
+		ifconfig ${1} ${2} > /dev/null 2>&1 || printf "\nFailed to set ${1} ${2} using ifconfig\n"
+	fi
+	return
+}
+
+ifaceIsUp() {
+	if [ -x "$(command -v ip 2>&1)" ]; then
+		ifaceIsUpCmd="ip link show dev"
+	elif [ -x "$(command -v ifconfig 2>&1)" ]; then
+		ifaceIsUpCmd="ifconfig"
+	fi
+	if ${ifaceIsUpCmd} ${1} 2>&1 | grep -q UP
+	then
+		return
+	else
+		return 1
+	fi
+}
+
+#listIfaceUnspec() {
+#	if [ -x "$(command -v ip 2>&1)" ]; then
+#		ip link 2>/dev/null | awk -F"[: ]+" '/UNSPEC/ {print $2}'
+#	elif [ -x "$(command -v ifconfig 2>&1)" ]; then
+#		ifconfig -a 2>/dev/null | awk -F"[: ]+" '/UNSPEC/ {print $1}'
+#	fi
+#}
+
+startDeprecatedIface() {
+	iwconfig ${1} mode monitor > /dev/null 2>&1
+	if [ -n "${2}" ]; then
+		if [ ${2} -lt 1000 ]; then
+			iwconfig ${1} channel ${2} > /dev/null 2>&1
+		else
+			iwconfig ${1} freq ${2}000000 > /dev/null 2>&1
+		fi
+	else
+		iwconfig ${1} channel ${CH} > /dev/null 2>&1
+	fi
+	iwconfig ${1} key off > /dev/null 2>&1
+	setLink ${1} up
+	printf " (monitor mode enabled)"
+}
+
+yesorno() {
+	read input
+	case $input in
+		y) return 0 ;;
+		yes) return 0 ;;
+		n) return 1 ;;
+		no) return 1 ;;
+		*) printf "\nInvalid input. Yes, or no? [y/n] "
+		   yesorno;;
+	esac
+}
+
+startMac80211Iface() {
+	#check if rfkill is set and cry if it is
+	rfkill_check ${PHYDEV}
+	rfkill_retcode="$?"
+	case ${rfkill_retcode} in
+		1) printf "\t${1} is soft blocked, please run \"rfkill unblock ${index}\" to use this interface.\n" ;;
+		2) printf "\t${1} is hard blocked, please flip the hardware wifi switch (or in BIOS) to on.\n"
+		   printf "\tIt may also be possible to unblock with \"rfkill unblock ${index}\"\n"
+		   if [ "${checkvm_status}" != "run" ]; then
+		   	checkvm
+		   fi
+		   if [ -n "${vm}" ]; then
+		   	printf "Detected VM using ${vm_from}\n"
+		   	printf "This appears to be a ${vm} Virtual Machine\n"
+		   	printf "Some distributions have bugs causing rfkill hard block to be forced on in a VM.\n"
+		   	printf "If toggling the rfkill hardware switch and \"rfkill unblock ${index}\" both fail\n"
+		   	printf "to fix this, please try not running in a VM.\n"
+		   fi
+		   ;;
+		3) printf "\t${1} is hard and soft blocked, please flip the hardware wifi switch to on.\n"
+		   printf "\tIt may also be needed to unblock with \"rfkill unblock ${index}\"\n" ;;
+	esac
+	if [ "${rfkill_retcode}" != 0 ]; then
+		printf "rfkill error, unable to start ${1}\n\n"
+		printf "Would you like to try and automatically resolve this? [y/n] "
+		yesorno
+		retcode="$?"
+		if [ "${retcode}" = "1" ]; then
+			return 1
+		elif [ "${retcode}" = "0" ]; then
+			rfkill_unblock ${PHYDEV}
+		fi
+	fi
+	#check if $1 already has a mon interface on the same phy and bail if it does
+	if [ -d /sys/class/ieee80211/${PHYDEV}/device/net ]; then
+		for i in $(ls /sys/class/ieee80211/${PHYDEV}/device/net/); do
+			if [ "$(cat /sys/class/ieee80211/${PHYDEV}/device/net/${i}/type)" = "803" ]; then
+				setChannelMac80211 ${i}
+				printf "\n\t\t(mac80211 monitor mode already enabled for [${PHYDEV}]${1} on [${PHYDEV}]${i})\n"
+				exit
+			fi
+		done
+	fi
+	#we didn't bail means we need a monitor interface
+	if [ ${#1} -gt 12 ]; then
+		printf "Interface ${1}mon is too long for linux so it will be renamed to the old style (wlan#) name.\n"
+		findFreeInterface monitor
+	else
+		if [ -e /sys/class/net/${1}mon ]; then
+			printf "\nYou already have a ${1}mon device but it is NOT in monitor mode."
+			printf "\nWhatever you did, don't do it again."
+			printf "\nPlease run \"iw ${1}mon del\" before attempting to continue\n"
+			exit 1
+		fi
+		#we didn't bail means our target interface is available
+		setLink ${1} down
+		if [ "${DRIVER}" = "8812au" ] || [ "${DRIVER}" = "8814au" ] || [ "${DRIVER}" = "88XXau" ]; then
+			#grumble grumble, seriously crap vendor driver
+			startDeprecatedIface ${1}
+			setChannelMac80211 ${1}
+			return
+		fi
+		IW_ERROR="$(iw phy ${PHYDEV} interface add ${1}mon type monitor 2>&1)"
+		if [ -z "${IW_ERROR}" ]; then
+			sleep 1
+			if [ -r "/sys/class/ieee80211/${PHYDEV}/device/net/${1}mon/type" ] && [ "$(cat /sys/class/ieee80211/${PHYDEV}/device/net/${1}mon/type)" = "803" ]; then
+				setChannelMac80211 ${1}mon
+			else
+				printf "\nNewly created monitor mode interface ${1}mon is *NOT* in monitor mode.\n"
+				printf "Removing non-monitor ${1}mon interface...\n"
+				stopMac80211Iface ${1}mon abort
+				exit 1
+			fi
+			printf "\n\t\t(mac80211 monitor mode vif enabled for [${PHYDEV}]${1} on [${PHYDEV}]${1}mon)\n"
+		else
+			printf "\n\nERROR adding monitor mode interface: ${IW_ERROR}\n"
+			exit 1
+		fi
+	fi
+	if [ "${ELITE}" = "1" ]; then
+		#check if $1 is still down, warn if not
+		if ifaceIsUp ${1}
+		then
+			printf "\nInterface ${1} is up, but it should be down. Something is interfering."
+			printf "\nPlease run \"airmon-ng check kill\" and/or kill your network manager."
+		fi
+	else
+		isRPiWireless && iw ${1} del
+		printf "\t\t(mac80211 station mode vif disabled for [${PHYDEV}]${1})\n"
+	fi
+}
+
+isRPiWireless() {
+	local HW_REV=$(grep Revision /proc/cpuinfo | awk '{print $3}')
+	[ -z "${HW_REV}" ] && return 0
+	# http://www.raspberrypi-spy.co.uk/2012/09/checking-your-raspberry-pi-board-version/
+	# https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
+	[ "${HW_REV}" = 'a22082' ] && return 1
+	[ "${HW_REV}" = 'a32082' ] && return 1
+	[ "${HW_REV}" = 'a52082' ] && return 1
+	[ "${HW_REV}" = 'a02082' ] && return 1
+	[ "${HW_REV}" = '9000c1' ] && return 1
+	[ "${HW_REV}" = 'a020d3' ] && return 1
+	[ "${HW_REV}" = '9020e0' ] && return 1
+	return 0
+}
+
+startwlIface() {
+	if [ -f "/proc/brcm_monitor0" ]; then
+		if [ -r "/proc/brcm_monitor0" ]; then
+			local brcm_monitor="$(cat /proc/brcm_monitor0)"
+			if [ "$brcm_monitor" = "1" ]; then
+				printf "\n\t\t(experimental wl monitor mode vif already enabled for [${PHYDEV}]${1} on [${PHYDEV}]prism0)\n"
+				return 0
+			fi
+		fi
+		if [ -w "/proc/brcm_monitor0" ]; then
+			printf "1" > /proc/brcm_monitor0
+			if [ "$?" = "0" ]; then
+				printf "\n\t\t(experimental wl monitor mode vif enabled for [${PHYDEV}]${1} on [${PHYDEV}]prism0)\n"
+			else
+				printf "\n\t\t(failed to enable experimental wl monitor mode for [${PHYDEV}${1})\n"
+			fi
+		else
+			printf "\n\tUnable to write to /proc/brcm_monitor0, cannot enable monitor mode.\n"
+		fi
+	else
+		printf "\n\tThis version of wl does not appear to support monitor mode.\n"
+	fi
+}
+
+#startDarwinIface() {
+#	if [ -x /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport ]; then
+#		if [ -n "${CH}" ] && [ ${CH} -lt 220 ]; then
+#			/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport $1 sniff ${CH}
+#		else
+#			printf "Channel is set to none channel value of ${CH}
+#		fi
+#	fi
+#}
+
+setChannelMac80211() {
+	setLink ${1} up
+	if [ -n "${CH}" ]; then
+		if [ ${CH} -lt 1000 ]; then
+			if [ -r "/sys/class/net/$1/phy80211/name" ]; then
+		                channel_list="$(iw phy $(cat /sys/class/net/$1/phy80211/name) info 2>&1 | awk -F'[][]' '$2{print $2}')"
+				local hardware_valid_channel=1
+	        	        for i in $channel_list; do
+	                	        if [ "${CH}" = "${i}" ]; then
+	                        	        hardware_valid_channel=0
+		                                break
+		                        fi
+		                done
+				if [ "${hardware_valid_channel}" = "1" ]; then
+	        	                printf "Channel ${CH} does not appear to be supported by ${1} hardware, defaulting to channel 3.\n\n"
+					CH=3
+				fi
+			fi
+			IW_ERROR="$(iw dev ${1} set channel ${CH} 2>&1)"
+		else
+			if [ -r "/sys/class/net/$1/phy80211/name" ]; then
+				frequency_list="$(iw phy $(cat /sys/class/net/$1/phy80211/name) info 2>&1 | sed -nr 's/.*( |^)([0-9]+) MHz .*/\2/p')"
+				local hardware_valid_freq=1
+				for i in $frequency_list; do
+					if [ "${CH}" = "${i}" ]; then
+						hardware_valid_freq=0
+						break
+					fi
+					print
+				done
+				if [ "${hardware_valid_freq}" = "1" ]; then
+					printf "Frequency ${CH} does not appear to be supported by ${1} hardware, defaulting to 2422 Mhz.\n\n"
+					CH="2422"
+				fi
+			fi
+			IW_ERROR="$(iw dev ${1} set freq "${CH}" 2>&1)"
+		fi
+	else
+		printf "CH is unset, this should not be possible.\n"
+		exit 1
+	fi
+	if [ -n "${IW_ERROR}" ]; then
+		printf "\nError setting channel: ${IW_ERROR}\n"
+		if printf "${IW_ERROR}" | grep -q "(-16)"; then
+			printf "Error -16 likely means your card was set back to station mode by something.\n"
+			printf "Removing non-monitor ${1} interface...\n"
+			stopMac80211Iface "${1}" abort
+			exit 1
+		fi
+		if printf "${IW_ERROR}" | grep -q "(-22)"; then
+			printf "Unable to set channel/frequency ${CH}, most likely it is outside of regulatory domain\n\n"
+		fi
+	fi
+}
+
+stopDeprecatedIface() {
+	setLink $1 down
+	iwconfig $1 mode Managed > /dev/null 2>&1
+	setLink $1 up
+	printf " (monitor mode disabled)"
+}
+
+stopMac80211Iface() {
+	if [ -f /sys/class/net/${1}/type ]; then
+		if [ "${2}" != "abort" ] && [ "$(cat /sys/class/net/${1}/type)" != "803" ]; then
+			printf "\n\nYou are trying to stop a device that isn't in monitor mode.\n"
+			printf "Doing so is a terrible idea, if you really want to do it then you\n"
+			printf "need to type 'iw ${1} del' yourself since it is a terrible idea.\n"
+			printf "Most likely you want to remove an interface called wlan[0-9]mon\n"
+			printf "If you feel you have reached this warning in error,\n"
+			printf "please report it.\n"
+			exit 1
+		else
+			if [ "${DRIVER}" = "8812au" ] || [ "${DRIVER}" = "8814au" ] || [ "${DRIVER}" = "88XXau" ]; then
+				#grumble grumble, seriously crap vendor driver
+				stopDeprecatedIface ${1}
+				return
+			fi
+			if [ "${ELITE}" = "0" ]; then
+				local need_sta=1
+				if [ -d /sys/class/ieee80211/${PHYDEV}/device/net ]; then
+					for i in $(ls /sys/class/ieee80211/${PHYDEV}/device/net/); do
+						if [ -r /sys/class/ieee80211/${PHYDEV}/device/net/${i}/type ] && [ "$(cat /sys/class/ieee80211/${PHYDEV}/device/net/${i}/type)" = "1" ]; then
+							[ "${2}" != "abort" ] && printf "\n\t\t(mac80211 station mode vif already available for [${PHYDEV}]${1} on [${PHYDEV}]${i})\n"
+							need_sta=0
+						fi
+					done
+				fi
+				if [ "${need_sta}" = "1" ] && [ -e /sys/class/net/${1%mon}/phy80211/name ]; then
+					if [ "$(cat /sys/class/net/${1%mon}/phy80211/name)" = "${PHYDEV}" ]; then
+						printf "\nYou already have a ${1%mon} device but it is NOT in station mode."
+						printf "\nWhatever you did, don't do it again."
+						printf "\nPlease run \"iw ${1%mon} del\" before attempting to continue\n"
+						exit 1
+					else
+						printf "\nYou already have a ${1%mon} device, but it is not on the same phy as ${1}.\n"
+						printf "\nAttemping to pick a new name...\n"
+						findFreeInterface station
+					fi
+				fi
+				if [ "${need_sta}" = "1" ]; then
+					IW_ERROR="$(iw phy ${PHYDEV} interface add ${1%mon} type station 2>&1)"
+					if [ -z "${IW_ERROR}" ]; then
+						interface="${1%mon}"
+						if [ -d /sys/class/ieee80211/${PHYDEV}/device/net ]; then
+							for i in $(ls /sys/class/ieee80211/${PHYDEV}/device/net/); do
+								if [ "$(cat /sys/class/ieee80211/${PHYDEV}/device/net/${i}/type)" = "1" ]; then
+									#here is where we catch udev renaming our interface
+									interface="${i}"
+								fi
+							done
+						fi
+						printf "\n\t\t(mac80211 station mode vif enabled on [${PHYDEV}]${interface})\n"
+					else
+						printf "\n\n ERROR adding station mode interface: ${IW_ERROR}\n"
+					fi
+				fi
+			fi
+			setLink ${1} down
+			IW_ERROR="$(iw dev "${1}" del 2>&1 | grep "nl80211 not found")"
+			if [ -z "$IW_ERROR" ]; then
+				if [ "${2}" != "abort" ]; then
+					printf "\n\t\t(mac80211 monitor mode vif disabled for [${PHYDEV}]${1})\n"
+				elif [ "${2}" = "abort" ]; then
+					printf "\nWARNING: unable to start monitor mode, please run \"airmon-ng check kill\"\n"
+				fi
+			else
+				if [ -f /sys/class/ieee80211/${PHYDEV}/remove_iface ]; then
+					printf "${1}" > /sys/class/ieee80211/${PHYDEV}/remove_iface
+					printf "\n\t\t(mac80211 monitor mode vif disabled for [${PHYDEV}]${1})\n"
+				else
+					printf "\n\nERROR: Neither the sysfs interface links nor the iw command is available.\nPlease download and install iw from\n$IW_SOURCE\n"
+				fi
+			fi
+		fi
+	fi
+}
+
+stopwlIface() {
+	if [ -f "/proc/brcm_monitor0" ]; then
+		if [ -r "/proc/brcm_monitor0" ]; then
+			local brcm_monitor="$(cat /proc/brcm_monitor0)"
+			if [ "$brcm_monitor" = "0" ]; then
+				printf "\n\t\t(experimental wl monitor mode vif already disabled for [${PHYDEV}]${1})\n"
+				return 0
+			fi
+		fi
+		if [ -w "/proc/brcm_monitor0" ]; then
+			printf "0" > /proc/brcm_monitor0
+			if [ "$?" = "0" ]; then
+				printf "\n\t\t(experimental wl monitor mode vif disabled for [${PHYDEV}]${1})\n"
+			else
+				printf "\n\t\t(failed to disable experimental wl monitor mode for [${PHYDEV}${1})\n"
+			fi
+		else
+			printf "\n\tUnable to write to /proc/brcm_monitor0, cannot disable monitor mode.\n"
+		fi
+	else
+		printf "\n\tThis version of wl does not appear to support monitor mode.\n"
+	fi
+}
+
+getDriver() {
+	unset DRIVER
+	#standard detection path, this is all that is needed for proper drivers
+	#DRIVER=$(printf "$ethtool_output" | awk '/driver/ {print $2}')
+
+	#if $(modinfo -F filename ${DRIVER} > /dev/null 2>&1)
+	#then
+	#	true
+	#else
+	#	unset DRIVER
+	#fi
+
+	#if [ "$DRIVER" = "" ]
+	#then
+		if [ -f /sys/class/net/$1/device/uevent ]; then
+			DRIVER="$(awk -F'=' '$1 == "DRIVER" {print $2}' /sys/class/net/$1/device/uevent)"
+		fi
+	#fi
+
+	#here we test for driver usb, ath9k_htc,rt2870, possibly others show this
+	if [ "$DRIVER" = "usb" ]; then
+		printf "Warn ON: USB\n"
+		BUSADDR="$(printf "$ethtool_output" | awk '/bus-info/ {print $2}'):1.0"
+
+		if [ "$DEBUG" = "1" ]; 	then
+			printf "${BUSADDR}\n"
+		fi
+
+		if [ -n "$BUSADDR" ]; then
+			if [ -f /sys/class/net/$1/device/"$BUSADDR"/uevent ]; then
+				DRIVER="$(awk -F'=' '$1 == "DRIVER" {print $2}' /sys/class/net/$1/device/$BUSADDR/uevent)"
+			fi
+		fi
+
+		#here we can normalize driver names we don't like
+		if [ "$DRIVER" = "rt2870" ]; then
+			DRIVER="rt2870sta"
+		fi
+		if [ -f /sys/class/net/$1/device/idProduct ]; then
+			if [ "$(cat /sys/class/net/$1/device/idProduct)" = "3070" ]; then
+				DRIVER="rt3070sta"
+			fi
+		fi
+	fi
+	if [ "$DRIVER" = "rtl8187L" ]; then
+		DRIVER="r8187l"
+	fi
+	if [ "$DRIVER" = "rtl8187" ] && [ "$STACK" = "ieee80211" ]; then
+		DRIVER="r8187"
+	fi
+	if [ "$DRIVER" = "rtl88xxau" ]; then
+		DRIVER="88XXau"
+	fi
+	if [ "$DRIVER" = "rtl8812au" ]; then
+		DRIVER="8812au"
+	fi
+
+	#Here we will catch the broken lying drivers not caught above
+	#currently this only functions for pci devices and not usb since lsusb has no -k option
+	if [ "${MODINFO}" = "1" ]; then
+		if $(modinfo -F filename $DRIVER  > /dev/null 2>&1)
+		then
+			true
+		else
+			save="$DRIVER"
+
+			if [ -n "${DEVICEID}" ] && [ "$BUS" = "pci" ]; then
+				DRIVER="$(lspci -d $DEVICEID -k | awk '/modules/ {print $3}')"
+			fi
+			if [ -z "${BUS}" ] || [ "${BUS}" != 'sdio' ]; then
+					unset DRIVER
+			fi
+
+			if [ -n "$save" ] && [ -z "$DRIVER" ] ; then
+				DRIVER="$save"
+			fi
+		fi
+	fi
+	if [ -z "$DRIVER" ] ; then
+		DRIVER="??????"
+	fi
+	if [ "$DEBUG" = "1" ]; then
+		printf "getdriver() $DRIVER\n"
+	fi
+}
+
+getFrom() {
+	#from detection
+	FROM="K"
+	if [ "${MODINFO}" = "1" ] && [ -f /proc/modules ]; then
+		if modinfo -F filename $DRIVER 2>&1 | grep -q 'kernel/drivers'
+		then
+			FROM="K"
+			#we add special handling here because we hate the vendor drivers AND they install in the wrong place
+			if [ "$DRIVER" = "r8187" ]; then
+				FROM="V"
+			elif [ "$DRIVER" = "r8187l" ]; then
+				FROM="V"
+			elif [ "$DRIVER" = "rt5390sta" ]; then
+				FROM="V"
+			elif [ "${DRIVER}" = "8812au" ] || [ "${DRIVER}" = "8814au" ]; then
+				FROM="V"
+			fi
+		elif modinfo -F filename $DRIVER 2>&1 | grep -q 'updates/drivers'
+		then
+			FROM="C"
+		elif modinfo -F filename $DRIVER 2>&1 | grep -q misc
+		then
+			FROM="V"
+		elif modinfo -F filename $DRIVER 2>&1 | grep -q staging
+		then
+			FROM="S"
+		else
+			FROM="?"
+		fi
+	else
+		FROM="K"
+	fi
+  #maybe add an 'intree' check?
+	if [ "$DEBUG" = "1" ]; then
+		printf "getFrom() $FROM\n"
+	fi
+}
+
+getFirmware() {
+	FIRMWARE="$(printf "$ethtool_output" | awk '/firmware-version/ {print $2}')"
+	#ath9k_htc firmware is a shorter version number than most so trap and make it pretty
+	if [ "$DRIVER" = "ath9k_htc" ]; then
+		FIRMWARE="$FIRMWARE\t"
+	fi
+
+	if [ "$FIRMWARE" = "N/A" ]; then
+		FIRMWARE="$FIRMWARE\t"
+	elif [ -z "$FIRMWARE" ]; then
+		FIRMWARE="unavailable"
+	fi
+
+	if [ "$DEBUG" = "1" ]; then
+		printf "getFirmware $FIRMWARE\n"
+	fi
+}
+
+getChipset() {
+	#this needs cleanup, we shouldn't have multiple lines assigning chipset per bus
+	#fix this to be one line per bus
+	if [ -f /sys/class/net/$1/device/modalias ]; then
+		if [ "$BUS" = "usb" ]; then
+			if [ "${LSUSB}" = "1" ]; then
+				BUSINFO="$(cut -d ":" -f 2 /sys/class/net/$1/device/modalias | cut -b 1-10 | sed 's/^.//;s/p/:/')"
+				CHIPSET="$(lsusb -d "$BUSINFO" | head -n1 - | cut -f3- -d ":" | sed 's/^....//;s/ Network Connection//g;s/ Wireless Adapter//g;s/^ //')"
+			elif [ "${LSUSB}" = "0" ]; then
+				printf "Your system doesn't seem to support usb but we found usb hardware, please report this.\n"
+				exit 1
+			fi
+		#yes the below line looks insane, but broadcom appears to define all the internal buses so we have to detect them here
+		elif [ "${BUS}" = "pci" -o "${BUS}" = "pcmcia" ] && [ "${LSPCI}" = "1" ]; then
+			if [ -f /sys/class/net/$1/device/vendor ] && [ -f /sys/class/net/$1/device/device ]; then
+				DEVICEID="$(cat /sys/class/net/$1/device/vendor):$(cat /sys/class/net/$1/device/device)"
+				CHIPSET="$(lspci -d $DEVICEID | cut -f3- -d ":" | sed 's/Wireless LAN Controller //g;s/ Network Connection//g;s/ Wireless Adapter//;s/^ //')"
+			else
+				BUSINFO="$(printf "$ethtool_output" | grep bus-info | cut -d ":" -f "3-" | sed 's/^ //')"
+				CHIPSET="$(lspci | grep "$BUSINFO" | head -n1 - | cut -f3- -d ":" | sed 's/Wireless LAN Controller //g;s/ Network Connection//g;s/ Wireless Adapter//;s/^ //')"
+				DEVICEID="$(lspci -nn | grep "$BUSINFO" | grep '[[0-9][0-9][0-9][0-9]:[0-9][0-9][0-9][0-9]' -o)"
+			fi
+		elif [ "${BUS}" = "sdio" ]; then
+			if [ -f /sys/class/net/$1/device/vendor ] && [ -f /sys/class/net/$1/device/device ]; then
+				DEVICEID="$(cat /sys/class/net/$1/device/vendor):$(cat /sys/class/net/$1/device/device)"
+			fi
+			if [ "${DEVICEID}" = '0x02d0:0x4330' ]; then
+				CHIPSET='Broadcom 4330'
+			elif [ "${DEVICEID}" = '0x02d0:0x4329' ]; then
+				CHIPSET='Broadcom 4329'
+			elif [ "${DEVICEID}" = '0x02d0:0x4334' ]; then
+				CHIPSET='Broadcom 4334'
+			elif [ "${DEVICEID}" = '0x02d0:0xa94c' ]; then
+				CHIPSET='Broadcom 43340'
+			elif [ "${DEVICEID}" = '0x02d0:0xa94d' ]; then
+				CHIPSET='Broadcom 43341'
+			elif [ "${DEVICEID}" = '0x02d0:0x4324' ]; then
+				CHIPSET='Broadcom 43241'
+			elif [ "${DEVICEID}" = '0x02d0:0x4335' ]; then
+				CHIPSET='Broadcom 4335/4339'
+			elif [ "${DEVICEID}" = '0x02d0:0xa962' ]; then
+				CHIPSET='Broadcom 43362'
+			elif [ "${DEVICEID}" = '0x02d0:0xa9a6' ]; then
+				CHIPSET='Broadcom 43430'
+			elif [ "${DEVICEID}" = '0x02d0:0x4345' ]; then
+				CHIPSET='Broadcom 43455'
+			elif [ "${DEVICEID}" = '0x02d0:0x4354' ]; then
+				CHIPSET='Broadcom 4354'
+			elif [ "${DEVICEID}" = '0x02d0:0xa887' ]; then
+				CHIPSET='Broadcom 43143'
+			else
+				CHIPSET="unable to detect for sdio $DEVICEID"
+			fi
+		else
+			CHIPSET="Not pci, usb, or sdio"
+		fi
+	#we don't do a check for usb here but it is obviously only going to work for usb
+	elif [ -f /sys/class/net/$1/device/idVendor ] && [ -f /sys/class/net/$1/device/idProduct ]; then
+		DEVICEID="$(cat /sys/class/net/$1/device/idVendor):$(cat /sys/class/net/$1/device/idProduct)"
+		if [ "${LSUSB}" = "1" ]; then
+			CHIPSET="$(lsusb | grep -i "$DEVICEID" | head -n1 - | cut -f3- -d ":" | sed 's/^....//;s/ Network Connection//g;s/ Wireless Adapter//g;s/^ //')"
+		elif [ "${LSUSB}" = "0" ]; then
+			CHIPSET="idVendor and idProduct found on non-usb device, please report this."
+		fi
+	elif [ "${DRIVER}" = "mac80211_hwsim" ]; then
+		CHIPSET="Software simulator of 802.11 radio(s) for mac80211"
+	elif $(printf "$ethtool_output" | awk '/bus-info/ {print $2}' | grep -q bcma)
+	then
+		BUS="bcma"
+
+		if [ "${DRIVER}" = "brcmsmac" ] || [ "${DRIVER}" = "brcmfmac" ] || [ "${DRIVER}" = "b43" ]; then
+			CHIPSET="Broadcom on bcma bus, information limited"
+		else
+			CHIPSET="Unrecognized driver \"${DRIVER}\" on bcma bus"
+		fi
+	else
+		CHIPSET="non-mac80211 device? (report this!)"
+	fi
+
+	if [ "$DEBUG" = "1" ]; then
+		printf "getchipset() $CHIPSET\n"
+		printf "BUS = $BUS\n"
+		printf "BUSINFO = $BUSINFO\n"
+		printf "DEVICEID = $DEVICEID\n"
+	fi
+}
+
+getBus() {
+	if [ -f /sys/class/net/$1/device/modalias ]; then
+		BUS="$(cut -d ":" -f 1 /sys/class/net/$1/device/modalias)"
+	fi
+	if [ "$DEBUG" = "1" ]; then
+		printf "getBus $BUS\n"
+	fi
+}
+
+getStack() {
+	if [ -z "$1" ]; then
+		return
+	fi
+
+	if [ -d /sys/class/net/$1/phy80211/ ]; then
+		MAC80211="1"
+		STACK="mac80211"
+	else
+		MAC80211="0"
+		STACK="ieee80211"
+	fi
+
+	if [ -e /proc/sys/dev/$1/fftxqmin ]; then
+		MAC80211="0"
+		STACK="net80211"
+	fi
+
+	if [ "$DEBUG" = "1" ]; then
+		printf "getStack $STACK\n"
+	fi
+}
+
+getExtendedInfo() {
+	#stuff rfkill info into extended if nothing else is there
+	rfkill_check ${PHYDEV}
+	rfkill_retcode="$?"
+	if [ "${rfkill_retcode}" = "1" ]; then
+		EXTENDED="rfkill soft blocked"
+	elif [ "${rfkill_retcode}" = "2" ]; then
+		EXTENDED="rfkill hard blocked"
+	elif [ "${rfkill_redcode}" = "3" ]; then
+		EXTENDED="rfkill hard and soft blocked"
+	fi
+
+	if [ "$DRIVER" = "??????" ]; then
+		EXTENDED="\t Failure detecting driver properly please report"
+	fi
+
+	#first we set all the real (useful) info we can find
+	if [ -f /sys/class/net/$1/device/product ]; then
+		EXTENDED="\t$(cat /sys/class/net/$1/device/product)"
+	fi
+
+	#then we sweep for known broken drivers with no available better drivers
+	if [ "$DRIVER" = "wl" ]; then
+		if [ -f "/proc/brcm_monitor0" ]; then
+			EXTENDED="Experimental monitor mode support"
+		else
+			EXTENDED="No known monitor support, try a newer version or b43"
+		fi
+	fi
+	if [ "$DRIVER" = "brcmsmac" ]; then
+		EXTENDED="Driver commonly referred to as brcm80211 (no injection yet)"
+	fi
+	if [ "$DRIVER" = "r8712u" ]; then
+		EXTENDED="\t\t\t\tNo monitor or injection support"
+	fi
+
+	#lastly we detect all the broken drivers which have working alternatives
+	KV="$(uname -r | awk -F'-' '{print $1}')"
+	KVMAJOR="$(printf ${KV} | awk -F'.' '{print $1$2}')"
+	KVMINOR="$(printf ${KV} | awk -F'.' '{print $3}')"
+
+	if [ $KVMAJOR -lt 26 ]; then
+		printf "You are running a kernel older than 2.6, I'm surprised it didn't error before now."
+	        if [ "$DEBUG" = "1" ]; then
+			printf "${KVMAJOR} ${KVMINOR}\n"
+		fi
+		exit 1
+	fi
+
+	if [ "$DRIVER" = "rt2870sta" ];	then
+		if [ "$KVMAJOR" = "26" ] && [ "$KVMINOR" -ge "35" ]; then
+			EXTENDED="\tBlacklist rt2870sta and use rt2800usb"
+		else
+			EXTENDED="\tUpgrade to kernel 2.6.35 or install compat-wireless stable"
+		fi
+		#add in a flag for "did you tell use to do X" and emit instructions
+	elif [ "$DRIVER" = "rt3070sta" ]; then
+		if [ "$KVMAJOR" = "26" ] && [ "$KVMINOR" -ge "35" ]; then
+			EXTENDED="\tBlacklist rt3070sta and use rt2800usb"
+		else
+			EXTENDED="\tUpgrade to kernel 2.6.35 or install compat-wireless stable"
+		fi
+	elif [ "$DRIVER" = "rt5390sta" ]; then
+		if [ "$KVMAJOR" = "26" ] && [ "$KVMINOR" -ge "39" ]; then
+			EXTENDED="\tBlacklist rt5390sta and use rt2800usb"
+		else
+			EXTENDED="\tUpgrade to kernel 2.6.39 or install compat-wireless stable"
+		fi
+	elif [ "$DRIVER" = "ar9170usb" ]; then
+		if [ "$KVMAJOR" = "26" ] && [ "$KVMINOR" -ge "37" ]; then
+			EXTENDED="\tBlacklist ar9170usb and use carl9170"
+		else
+			EXTENDED="\tUpgrade to kernel 2.6.37 or install compat-wireless stable"
+		fi
+	elif [ "$DRIVER" = "arusb_lnx" ]; then
+		if [ "$KVMAJOR" = "26" ] && [ "$KVMINOR" -ge "37" ]; then
+			EXTENDED="\tBlacklist arusb_lnx and use carl9170"
+		else
+			EXTENDED="\tUpgrade to kernel 2.6.37 or install compat-wireless stable"
+		fi
+	elif [ "$DRIVER" = "r8187" ]; then
+		if [ "$KVMAJOR" = "26" ] && [ "$KVMINOR" -ge "29" ]; then
+			EXTENDED="\t\tBlacklist r8187 and use rtl8187 from the kernel"
+		else
+			EXTENDED="\t\tUpgrade to kernel 2.6.29 or install compat-wireless stable"
+		fi
+	elif [ "$DRIVER" = "r8187l" ]; then
+		if [ "$KVMAJOR" = "26" ] && [ "$KVMINOR" -ge "29" ]; then
+			EXTENDED="\t\tBlacklist r8187l and use rtl8187 from the kernel"
+		else
+			EXTENDED="\t\tUpgrade to kernel 2.6.29 or install compat-wireless stable"
+		fi
+	fi
+	#okay, now I take overload to a new level
+	#if there is nothing else here to complain about, show mode
+	if [ -z "${EXTENDED}" ]; then
+		if [ -r "/sys/class/net/${1}/type" ]; then
+			NET_TYPE="$(cat /sys/class/net/${1}/type)"
+		elif [ -r "/sys/class/ieee80211/${PHYDEV}/device/net/${1}/type" ]; then
+			NET_TYPE="$(cat /sys/class/ieee80211/${PHYDEV}/device/net/${1}/type)"
+		fi
+		if [ -n "${NET_TYPE}" ]; then
+			if [ "${NET_TYPE}" = "803" ]; then
+				EXTENDED="mode monitor"
+			elif [ "${NET_TYPE}" = "1" ]; then
+				EXTENDED="mode managed"
+			else
+				EXTENDED="mode ${NET_TYPE} unknown"
+			fi
+		fi
+	fi
+}
+
+scanProcesses() {
+	#this test means it errored and said it was busybox since busybox doesn't print without error
+	if (ps -A 2>&1 | grep -q BusyBox)
+	then
+		#busybox in openwrt cannot handle -A but its output by default is -A
+		psopts=""
+	else
+		psopts="-A"
+	fi
+	if ( ps -o comm= 2>&1 | grep -q BusyBox )
+	then
+		#busybox in openwrt cannot handle -o
+		pso="0"
+	else
+		pso="1"
+	fi
+
+	PROCESSES="wpa_action\|wpa_supplicant\|wpa_cli\|dhclient\|ifplugd\|dhcdbd\|dhcpcd\|udhcpc\|NetworkManager\|knetworkmanager\|avahi-autoipd\|avahi-daemon\|wlassistant\|wifibox"
+	#PS_ERROR="invalid\|illegal"
+
+	if [ -x "$(command -v service 2>&1)" ] && [ "$1" = "kill" ]; then
+		service network-manager stop 2> /dev/null > /dev/null
+		service NetworkManager stop 2> /dev/null > /dev/null
+		service avahi-daemon stop 2> /dev/null > /dev/null
+	fi
+
+	unset match
+	if [ "${pso}" = 1 ]; then
+		match="$(ps ${psopts} -o comm= | grep ${PROCESSES} | grep -v grep | wc -l)"
+	elif [ "${pso}" = 0 ]; then
+		#openwrt busybox grep hits on itself so we -v it out
+		match="$(ps ${psopts} | grep ${PROCESSES} | grep -v grep | wc -l)"
+	fi
+	if [ ${match} -gt 0 ] && [ "${1}" != "kill" ]; then
+		printf "Found $match processes that could cause trouble.\n"
+		printf "Kill them using 'airmon-ng check kill' before putting\n"
+		printf "the card in monitor mode, they will interfere by changing channels\n"
+		printf "and sometimes putting the interface back in managed mode\n\n"
+	else
+		if [ "${1}" != "kill" ] && [ -n "${1}" ]; then
+			printf "No interfering processes found\n"
+			return
+		fi
+	fi
+
+	if [ ${match} -gt 0 ]; then
+		if [ "${1}" = "kill" ]; then
+			printf "Killing these processes:\n\n"
+		fi
+		if [ "${pso}" = "1" ]; then
+			ps ${psopts} -o pid=PID -o comm=Name | grep "${PROCESSES}\|PID"
+		else
+			#openwrt busybox grep hits on itself so we -v it out
+			ps ${psopts} | grep "${PROCESSES}\|PID | grep -v grep"
+		fi
+		if [ "${1}" = "kill" ]; then
+			#we have to use signal 9 because things like nm actually respawn wpa_supplicant too quickly
+			if [ "${pso}" = "1" ]; then
+				for pid in $(ps ${psopts} -o pid= -o comm= | grep ${PROCESSES} | awk '{print $1}'); do
+					kill -9 ${pid}
+				done
+			else
+				#openwrt busybox grep hits on itself so we -v it out
+				for pid in $(ps ${psopts} | grep ${PROCESSES} | grep -v grep | awk '{print $1}'); do
+					kill -9 ${pid}
+				done
+			fi
+		fi
+	fi
+
+	#i=1
+	#while [ $i -le $match ]
+	#do
+	#	pid=$(ps ${psopts} -o pid= -o comm= | grep $PROCESSES | head -n $i | tail -n 1 | awk '{print $1}')
+	#	pname=$(ps ${psopts} -o pid= -o comm= | grep $PROCESSES | head -n $i | tail -n 1 | awk '{print $2}')
+	#	if [ x"$1" != "xkill" ]
+	#	then
+	#		printf "${pid}\t${pname}\n"
+	#	else
+	#		kill ${pid}
+	#	fi
+	#	i=$(($i+1))
+	#done
+
+	printf "\n"
+
+	#this stub is for checking against the interface name, but since it almost never hits why bother?
+	#if [ x"${1}" != "x" -a x"${1}" != "xkill" ]
+	#then
+	#	#the next line doesn't work on busybox ps because -p is unimplimented
+	#	match2=$(ps -o comm= -p 1 2>&1 | grep $PS_ERROR -c)
+	#	if [ ${match2} -gt 0 ]
+	#	then
+	#		return
+	#	fi
+	#
+	#	for i in $(ps auxw | grep ${1} | grep -v "grep" | grep -v "airmon-ng" | awk '{print $2}')
+	#	do
+	#		pname=$(ps -o comm= -p ${i})
+	#		printf "Process with PID ${i} ($pname) is running on interface ${1}\n"
+	#	done
+	#fi
+}
+
+listInterfaces() {
+	unset iface_list
+	for iface in $(ls -1 /sys/class/net)
+	do
+		if [ -f /sys/class/net/${iface}/uevent ]; then
+			if $(grep -q DEVTYPE=wlan /sys/class/net/${iface}/uevent)
+			then
+				iface_list="${iface_list}\n ${iface}"
+			fi
+		fi
+	done
+
+	# this block only adds garbage to me
+	#if [ -x "$(command -v iwconfig 2>&1)" ] && [ -x "$(command -v sort 2>&1)" ]; then
+	#	for iface in $(iwconfig 2> /dev/null | sed 's/^\([a-zA-Z0-9_.]*\) .*/\1/'); do
+	#		iface_list="${iface_list}\n ${iface}"
+	#	done
+	#	iface_list="$(printf "${iface_list}" | sort -bu)"
+	#fi
+}
+
+getPhy() {
+	if [ -z "$1" ];	then
+		return
+	fi
+
+	if [ $MAC80211 = "0" ]; then
+		PHYDEV="null"
+		return
+	fi
+
+	if [ -r /sys/class/net/$1/phy80211/name ]; then
+		PHYDEV="$(cat /sys/class/net/$1/phy80211/name)"
+	fi
+	if [ -d /sys/class/net/$1/phy80211/ ] && [ -z "${PHYDEV}" ]; then
+
+		PHYDEV="$(ls -l "/sys/class/net/$1/phy80211" | sed 's/^.*\/\([a-zA-Z0-9_-]*\)$/\1/')"
+	fi
+}
+
+checkvm() {
+	#this entire section of code is completely stolen from Carlos Perez's work in checkvm.rb for metasploit and rewritten (poorly) in sh
+	#check loaded modules
+	if [ -x "$(command -v lsmod 2>&1)" ]; then
+		lsmod_data="$(lsmod 2>&1 | awk '{print $1}')"
+		if [ -n "${lsmod}" ]; then
+			printf "${lsmod_data}" | grep -iqE "vboxsf|vboxguest" 2> /dev/null && vm="VirtualBox"
+			printf "${lsmod_data}" | grep -iqE "vmw_ballon|vmxnet|vmw" 2> /dev/null && vm="VMware"
+			printf "${lsmod_data}" | grep -iqE "xen-vbd|xen-vnif" 2> /dev/null && vm="Xen"
+			printf "${lsmod_data}" | grep -iqE "virtio_pci|virtio_net" 2> /dev/null && vm="Qemu/KVM"
+			printf "${lsmod_data}" | grep -iqE "hv_vmbus|hv_blkvsc|hv_netvsc|hv_utils|hv_storvsc" && vm="MS Hyper-V"
+			[ -n "${vm}" ] && vm_from="lsmod"
+		fi
+	fi
+
+	#check scsi driver
+	if [ -z "${vm_from}" ]; then
+		if [ -r /proc/scsi/scsi ]; then
+			grep -iq "vmware" /proc/scsi/scsi 2> /dev/null && vm="VMware"
+			grep -iq "vbox" /proc/scsi/scsi 2> /dev/null && vm="VirtualBox"
+			[ -n "${vm}" ] && vm_from="/pro/scsi/scsi"
+		fi
+	fi
+
+	# Check IDE Devices
+	if [ -z "${vm_from}" ];	then
+		if [ -d /proc/ide ]; then
+			ide_model="$(cat /proc/ide/hd*/model)"
+			printf "${ide_model}" | grep -iq "vbox" 2> /dev/null && vm="VirtualBox"
+			printf "${ide_model}" | grep -iq "vmware" 2> /dev/null && vm="VMware"
+			printf "${ide_model}" | grep -iq "qemu" 2> /dev/null && vm="Qemu/KVM"
+			printf "${ide_model}" | grep -iqE "virtual (hd|cd)" 2> /dev/null && vm="Hyper-V/Virtual PC"
+			[ -n "${vm}" ] && vm_from="ide_model"
+		fi
+	fi
+
+	# Check using lspci
+	if [ -z "${vm_from}" ] && [ "${LSPCI}" = "1" ]; then
+			lspci_data="$(lspci 2>&1)"
+			printf "${lspci_data}" | grep -iq "vmware" 2> /dev/null && vm="VMware"
+			printf "${lspci_data}" | grep -iq "virtualbox" 2> /dev/null && vm="VirtualBox"
+			[ -n "${vm}" ] && vm_from="lspci"
+	fi
+
+	# Xen bus check
+	## XXX: Removing unsafe check
+	# this check triggers if CONFIG_XEN_PRIVILEGED_GUEST=y et al are set in kconfig (debian default) even in not actually a guest
+	#if [ -z ${vm} ]
+	#then
+	#	ls -1 /sys/bus | grep -iq "xen" 2> /dev/null && vm="Xen"
+	#	vm_from="/sys/bus/xen"
+	#fi
+
+	# Check using lscpu
+	if [ -z "${vm_from}" ]; then
+		if [ -x "$(command -v lscpu 2>&1)" ]; then
+                        lscpu_data="$(lscpu 2>&1)"
+			printf "${lscpu_data}" | grep -iq "Xen" 2> /dev/null && vm="Xen"
+			printf "${lscpu_data}" | grep -iq "KVM" 2> /dev/null && vm="KVM"
+			printf "${lscpu_data}" | grep -iq "Microsoft" 2> /dev/null && vm="MS Hyper-V"
+			[ -n "${vm}" ] && vm_from="lscpu"
+		fi
+	fi
+
+	#Check vmnet
+	if [ -z "${vm_from}" ]; then
+		if [ -e /dev/vmnet ]; then
+			vm="VMware"
+			vm_from="/dev/vmnet"
+		fi
+	fi
+
+	#Check dmi info
+	if [ -z "${vm_from}" ]; then
+		if [ -x "$(command -v dmidecode 2>&1)" ]; then
+			dmidecode 2>&1 | grep -iq "microsoft corporation" 2> /dev/null && vm="MS Hyper-V"
+			dmidecode 2>&1 | grep -iq "vmware" 2> /dev/null && vm="VMware"
+			dmidecode 2>&1 | grep -iq "virtualbox" 2> /dev/null && vm="VirtualBox"
+			dmidecode 2>&1 | grep -iq "qemu" 2> /dev/null && vm="Qemu/KVM"
+			dmidecode 2>&1 | grep -iq "domu" 2> /dev/null && vm="Xen"
+			[ -n "${vm}" ] && vm_from="dmi_info"
+		fi
+	fi
+
+	# Check dmesg Output
+	if [ -z "${vm_from}" ]; then
+		if [ -x "$(command -v dmesg 2>&1)" ]; then
+			dmesg | grep -iqE "vboxbios|vboxcput|vboxfacp|vboxxsdt|(vbox cd-rom)|(vbox harddisk)" && vm="VirtualBox"
+			dmesg | grep -iqE "(vmware virtual ide)|(vmware pvscsi)|(vmware virtual platform)" && vm="VMware"
+			dmesg | grep -iqE "(xen_mem)|(xen-vbd)" && vm="Xen"
+			dmesg | grep -iqE "(qemu virtual cpu version)" && vm="Qemu/KVM"
+			[ -n "${vm}" ] && vm_from="dmesg"
+		fi
+	fi
+	checkvm_status="run"
+}
+
+#end function definitions
+#begin execution
+
+#here we check for any phys that have no interfaces to pick up The Lost Phys
+handleLostPhys
+
+listInterfaces
+
+if [ "${1}" = "check" ] || [ "${1}" = "start" ]; then
+	if [ "${2}" = "kill" ]; then
+		#if we are killing, tell scanProcesses that
+		scanProcesses "${2}"
+		exit
+	elif [ "${1}" = "start" ]; then
+		#this stub can send scanProcesses the interface name
+		#but this seems entirely unreliable so just run generic
+		#scanProcesses "${2}"
+		scanProcesses
+	else
+		scanProcesses
+		exit
+	fi
+fi
+
+if [ "$#" != "0" ]; then
+	if [ "$1" != "start" ] && [ "$1" != "stop" ]; then
+		usage
+	fi
+
+	if [ -z "$2" ]; then
+		usage
+	fi
+fi
+
+#startup checks complete, headers then main
+
+if [ "$DEBUG" = "1" ]; then
+	if [ -x "$(command -v readlink 2>&1)" ]; then
+		printf "/bin/sh -> $(readlink -f /bin/sh)\n"
+		if $(readlink -f /bin/sh) --version > /dev/null 2>&1
+		then
+			printf "$($(readlink -f /bin/sh) --version)\n"
+		fi
+	else
+		ls -l /bin/sh
+		if /bin/sh --version > /dev/null 2>&1
+		then
+			/bin/sh --version
+		fi
+	fi
+	if [ -n "$SHELL" ]; then
+		if $SHELL --version > /dev/null 2>&1
+		then
+			printf "\nSHELL is $($SHELL --version)\n\n"
+		else
+			printf "\nSHELL is $SHELL\n\n"
+		fi
+	fi
+fi
+if [ "$VERBOSE" = "1" ]; then
+	if [ -n "$(command -v lsb_release 2> /dev/null)" ]; then
+		lsb_release -a
+		printf "\n"
+	fi
+	uname -a
+
+	checkvm
+	if [ -n "${vm}" ]; then
+		printf "Detected VM using ${vm_from}\n"
+		printf "This appears to be a ${vm} Virtual Machine\n"
+		printf "If your system supports VT-d, it may be possible to use PCI devices\n"
+		printf "If your system does not support VT-d, you can only use USB wifi cards\n"
+	fi
+
+	printf "\nK indicates driver is from $(uname -r)\n"
+	if [ "${MODPROBE}" = "1" ]; then
+		modprobe compat > /dev/null 2>&1
+
+		if [ -r /sys/module/compat/parameters/compat_version ]; then
+			printf "C indicates driver is from $(cat /sys/module/compat/parameters/compat_version)\n"
+		fi
+	fi
+	printf "V indicates driver comes directly from the vendor, almost certainly a bad thing\n"
+	printf "S indicates driver comes from the staging tree, these drivers are meant for reference not actual use, BEWARE\n"
+	printf "? indicates we do not know where the driver comes from... report this\n\n"
+fi
+
+if [ "${VERBOSE}" = "1" ]; then
+	printf "\nX[PHY]Interface\t\tDriver[Stack]-FirmwareRev\t\tChipset\t\t\t\t\t\t\t\t\t\tExtended Info\n\n"
+else
+	printf "PHY\tInterface\tDriver\t\tChipset\n\n"
+fi
+
+#this whole block of code shouldn't be here, it makes no sense
+#per shellcheck, this block is broken as it runs the loops once with iface=listIfaceUnspec instead of the output of listIFaceUnspec
+#for iface in listIfaceUnspec; do
+#
+#	if [ -e "/proc/sys/dev/$iface/fftxqmin" ]
+#	then
+#		setLink ${iface} up
+#		printf "$iface\t\tAtheros\t\tmadwifi-ng"
+#		if [ x$1 = "xstart" ] && [ x$2 = x$iface ]
+#		then
+#			IFACE=$(wlanconfig ath create wlandev $iface wlanmode monitor -bssid | grep ath)
+#			setLink ${iface} up
+#			if [ $CH -lt 1000 ]
+#			then
+#				iwconfig $IFACE channel $CH 2> /dev/null > /dev/null
+#			else
+#				iwconfig $IFACE freq "$CH"000000 2> /dev/null > /dev/null
+#			fi
+#		setLink ${IFACE} up
+#		UDEV_ISSUE=$?
+#		fi
+#
+#		if [ x$1 = "xstop" ] && [ x$2 = x$iface ]
+#		then
+#			printf "$iface does not support 'stop', do it on ath interface\n"
+#		fi
+#
+#		#why, dear god why is there a random newline here?
+#		printf "\n"
+#		sleep 1
+#		continue
+#	fi
+#done
+#end random block of code that needs to die
+
+for iface in $(printf "${iface_list}"); do
+	unset ethtool_output DRIVER FROM FIRMWARE STACK MADWIFI MAC80211 BUS BUSADDR BUSINFO DEVICEID CHIPSET EXTENDED NET_TYPE PHYDEV ifacet DRIVERt FIELD1 FIELD1t FIELD2 FIELD2t CHIPSETt
+	#add a RUNNING check here and up the device if it isn't already
+	ethtool_output="$(ethtool -i $iface 2>&1)"
+	if [ "$ethtool_output" != "Cannot get driver information: Operation not supported" ]; then
+		getStack  ${iface}
+		getBus ${iface}
+		getPhy     ${iface}
+		getDriver   ${iface}
+		getChipset ${iface}
+		if [ "${VERBOSE}" = "1" ]; then
+			getFrom ${iface}
+			getFirmware ${iface}
+			getExtendedInfo ${iface}
+		fi
+	else
+ 		printf "\nethtool failed...\n"
+		printf "Only mac80211 devices on kernel 2.6.33 or higher are officially supported by airmon-ng.\n"
+		exit 1
+	fi
+
+	#yes this really is the main output loop
+	if [ "${VERBOSE}" = "1" ]; then
+		#beautify output spacing (within reason)
+		FIELD1="${FROM}[${PHYDEV}]${iface}"
+		if [ ${#FIELD1} -gt 15 ]; then
+			FIELD1t="\t"
+		else
+			FIELD1t="\t\t"
+		fi
+		FIELD2="${DRIVER}[${STACK}]-${FIRMWARE}"
+		if [ ${#FIELD2} -gt 28 ]; then
+			FIELD2t="\t"
+		else
+			FIELD2t="\t\t"
+		fi
+		if [ -n "${EXTENDED}" ]; then
+			if [ ${#CHIPSET} -gt 70 ]; then
+				CHIPSETt="\t"
+			elif [ ${#CHIPSET} -gt 63 ]; then
+				CHIPSETt="\t\t"
+			elif [ ${#CHIPSET} -gt 56 ]; then
+				CHIPSETt="\t\t\t"
+			elif [ ${#CHIPSET} -gt 49 ]; then
+				CHIPSETt="\t\t\t\t"
+			elif [ ${#CHIPSET} -gt 39 ]; then
+				CHIPSETt="\t\t\t\t\t"
+			elif [ ${#CHIPSET} -gt 35 ]; then
+				CHIPSETt="\t\t\t\t\t\t"
+			# XXX YUP, 28 and 21 are now that same. mostly because this is all hardcoded and sucks
+			elif [ ${#CHIPSET} -gt 28 ]; then
+				CHIPSETt="\t\t\t\t\t\t\t"
+			elif [ ${#CHIPSET} -gt 21 ]; then
+				CHIPSETt="\t\t\t\t\t\t\t"
+			elif [ ${#CHIPSET} -gt 14 ]; then
+				CHIPSETt="\t\t\t\t\t\t\t\t"
+			elif [ ${#CHIPSET} -gt 7 ]; then
+				CHIPSETt="\t\t\t\t\t\t\t\t\t"
+			else
+				CHIPSETt="\t\t\t\t\t\t\t\t\t\t"
+			fi
+		fi
+		printf "${FROM}[${PHYDEV}]${iface}${FIELD1t}${DRIVER}[${STACK}]-${FIRMWARE}${FIELD2t}${CHIPSET}${CHIPSETt}${EXTENDED}\n"
+	else
+		#beautify output spacing (within reason, interface/driver max length is 15 and phy max length is 7))
+		if [ ${#DRIVER} -gt 7 ]; then
+			DRIVERt="\t"
+		else
+			DRIVERt="\t\t"
+		fi
+		if [ ${#iface} -gt 7 ]; then
+			ifacet="\t"
+		else
+			ifacet="\t\t"
+		fi
+		printf "${PHYDEV}\t${iface}${ifacet}${DRIVER}${DRIVERt}${CHIPSET}\n"
+	fi
+
+	if [ "$DRIVER" = "wl" ]; then
+		if [ "$1" = "start" ] && [ "$2" = "$iface" ]; then
+			startwlIface $iface
+		fi
+		if [ "$1" = "stop" ] && [ "$2" = "$iface" ]; then
+			stopwlIface $iface
+		fi
+	elif [ "$MAC80211" = "1" ]; then
+		if [ "$1" = "start" ] && [ "$2" = "$iface" ]; then
+			startMac80211Iface $iface
+		fi
+
+		if [ "$1" = "stop" ] && [ "$2" = "$iface" ]; then
+			stopMac80211Iface $iface
+		fi
+	fi
+done
+
+#end with some space
+printf "\n"

+ 190 - 0
files/common/usr/wpc-tools

@@ -0,0 +1,190 @@
+#!/bin/sh
+# Copyright (C) 2023 DSR!
+
+COMMANDS="format_sd correct_sd_mount missing_packages theme_install set_panel_port set_router_ip set_pineap_interface handle_lost_phys"
+HELP="
+Available commands:
+    format_sd            Format SD/pendrive for use with Pineapple
+    correct_sd_mount     Fix ghost SD/pendrive issues
+    missing_packages     Install the missing OpenWRT packages
+    theme_install        Deploys the tool to change panel theme
+    set_panel_port       Change the port used by panel
+    set_router_ip        Change the IP used by the hardware
+    set_pineap_interface Change the interface used by PineAP 
+    handle_lost_phys     Fix unrecognized wifi interfaces
+"
+PACKAGES="python-logging python-openssl python-sqlite3 python-codecs"
+
+to_logger() {
+    logger -s -t wpc "$1"
+}
+
+format_sd() {
+    to_logger "[+] Formatting SD using the panel script..."
+    /pineapple/modules/Advanced/formatSD/format_sd
+    to_logger "Process finished. Read the log to see if it was completed correctly."
+    to_logger "The partition may take a few seconds to become available."
+}
+
+correct_sd_mount() {
+    SD_STATUS=$(/bin/mount | /bin/grep "on /sd" -c)
+    SD_COUNT=$(ls /sd | wc -l)
+    if [[ -d /sd && $SD_STATUS == "0" && $SD_COUNT == "0" ]]; then
+        to_logger "[+] Fix sd status"
+        rm -rf /sd
+    fi
+}
+
+missing_packages() {
+    if [[ ! -d "/usr/lib/python2.7" && ! -d "/sd/usr/lib/python2.7" ]]; then
+        FREE_SPACE=$(df / | tail -1 | awk '{print $4}')
+
+        if [[ ! -d /sd && $FREE_SPACE -lt 10240 ]]; then
+            to_logger "[!] There is not enough space to install the packages"
+        elif ping -q -c 1 -W 1 1.1.1.1 >/dev/null; then
+            to_logger "[+] Installing missing packages..."
+            INSTALL_ROUTE="--dest sd"
+            if [[ $FREE_SPACE -gt 10240 ]]; then
+                INSTALL_ROUTE=""
+                to_logger "[*] Found available space in the system partition"
+            fi
+
+            opkg update && opkg $INSTALL_ROUTE install $PACKAGES && python -m compileall
+            if [[ ! -d "/usr/lib/python2.7" && ! -d "/sd/usr/lib/python2.7" ]]; then
+                to_logger "[!] Packages were not installed!"
+            else
+                to_logger "[*] Install Complete!"
+            fi
+        else
+            to_logger "[!] Connect to the internet and run \"wpc-tools missing_packages\" command!"
+        fi
+    fi
+}
+
+theme_install() {
+    to_logger "[+] Downloading theme manager..."
+    wget -q "https://raw.githubusercontent.com/xchwarze/wifi-pineapple-community/main/themes/install.sh" -O /tmp/theme-install.sh
+    chmod +x /tmp/theme-install.sh
+    to_logger "[*] By running /tmp/theme-install.sh you will be able to see the available themes and choose the one you want"
+    /tmp/theme-install.sh "$1"
+}
+
+set_panel_port() {
+    new_port="$1"
+    config_file="/etc/nginx/nginx.conf"
+    if [ -z "$new_port" ] || ! echo "$new_port" | grep -qE '^[1-9][0-9]{0,4}$' || [ "$new_port" -gt 65535 ]; then
+        to_logger "[!] Error: You must provide a valid TCP port (1-65535) as a parameter"
+        exit 1
+    fi
+
+    old_port=$(awk '/listen/ {++counter; if(counter==2) print NR}' "$config_file")
+    sed -i "${old_port}s/[0-9]\+/$new_port/" "$config_file"
+    /etc/init.d/nginx restart
+
+    uci set firewall.allowui.dest_port="$new_port"
+    uci commit firewall
+    /etc/init.d/firewall restart
+    
+    to_logger "[+] The port has been changed to: $new_port"
+}
+
+set_router_ip() {
+    new_ip="$1"
+    if [ -z "$new_ip" ] || ! echo "$new_ip" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$'; then
+        to_logger "[!] Error: You must provide a valid IP address as a parameter"
+        exit 1
+    fi
+
+    gateway_ip="${new_ip%.*}.42"
+    uci set network.lan.ipaddr="$gateway_ip"
+    uci set network.lan.gateway="$new_ip"
+    uci commit network
+
+    to_logger "[+] The LAN IP address has been updated to: $new_ip"
+    /etc/init.d/network restart
+}
+
+set_pineap_interface() {
+    new_iface=$(echo $1 | sed 's/mon//')
+    iface=$(uci get pineap.@config[0].pineap_interface | sed 's/mon//')
+    if [[ "$new_iface" == "" ]]; then  
+        to_logger "[!] Error: You must select a new interface to assign to"
+        exit 1
+    fi
+
+    to_logger "[+] Current interface : ${iface}"
+    to_logger "[+] New interface     : ${new_iface}"
+
+    airmon-ng stop "${iface}mon" &>/dev/null 
+    airmon-ng stop "${new_iface}mon" &>/dev/null 
+
+    uci set pineap.@config[0].pineap_interface="${new_iface}mon"
+    uci commit pineap           
+
+    /etc/init.d/pineapd restart
+}
+
+# based on airmon-ng code
+handle_lost_phys() {
+    to_logger "[+] Looking for unrecognized wifi interfaces..."
+    if [ -d /sys/class/ieee80211 ]; then
+        for i in $(ls /sys/class/ieee80211/); do
+            if [ ! -d /sys/class/ieee80211/${i}/device/net ]; then
+                to_logger "[*] Found ${i} with no interface assigned!"
+                find_free_interface ${i}
+            fi
+        done
+    fi
+    to_logger "[*] Check completed"
+}
+
+find_free_interface() {
+    PHYDEV="${1}"
+    target_mode="station"
+    target_type="1"
+
+    for i in $(seq 0 100); do
+        if [ "$i" = "100" ]; then
+            to_logger "[!] Unable to find a free name between wlan0 and wlan99"
+            return 1
+        fi
+
+        if [ ! -e /sys/class/net/wlan${i} ] && [ ! -e /sys/class/net/wlan${i}mon ]; then
+            to_logger "[*] Candidate wlan${i} and wlan${i}mon are both clear, creating wlan${i}"
+
+            IW_ERROR="$(iw phy ${PHYDEV} interface add wlan${i} type ${target_mode} 2>&1)"
+            if [ -z "${IW_ERROR}" ]; then
+                if [ -d /sys/class/ieee80211/${PHYDEV}/device/net ]; then
+                    for j in $(ls /sys/class/ieee80211/${PHYDEV}/device/net/); do
+                        if [ "$(cat /sys/class/ieee80211/${PHYDEV}/device/net/${j}/type)" = "${target_type}" ]; then
+                            k=${j#wlan}
+                            i=${k%mon}
+                        fi
+                    done
+                else
+                    to_logger "[!] Unable to create wlan${i} and no error received"
+                    return 1
+                fi
+
+                to_logger "[!] mac80211 ${target_mode} mode vif enabled on [${PHYDEV}]wlan${i}"
+                unset IW_ERROR
+                break
+            else
+                to_logger "[!] Error: Adding ${target_mode} mode interface: ${IW_ERROR}"
+                break
+            fi
+        fi
+    done
+}
+
+# handle commands
+if [[ $# -gt 0 ]]; then
+    if echo "${COMMANDS}" | grep -wq "$1"; then
+        $1 "$2"
+    else
+        to_logger "Unknown command: $1"
+        echo "${HELP}"
+    fi
+else
+    echo "${HELP}"
+fi

+ 2 - 0
files/mips/customfeeds.conf

@@ -0,0 +1,2 @@
+# Community Packages
+src/gz community_packages https://raw.githubusercontent.com/xchwarze/wifi-pineapple-community/main/packages/mips_24kc

BIN
files/mips/python/encodings/__init__.pyc


BIN
files/mips/python/encodings/aliases.pyc


BIN
files/mips/python/encodings/base64_codec.pyc


BIN
files/mips/python/encodings/hex_codec.pyc


+ 2 - 0
files/mipsel/customfeeds.conf

@@ -0,0 +1,2 @@
+# Community Packages
+src/gz community_packages https://raw.githubusercontent.com/xchwarze/wifi-pineapple-community/main/packages/mipsel_24kc

BIN
files/mipsel/python/encodings/__init__.pyc


BIN
files/mipsel/python/encodings/aliases.pyc


BIN
files/mipsel/python/encodings/base64_codec.pyc


BIN
files/mipsel/python/encodings/hex_codec.pyc


+ 118 - 0
lists/nano.filelist

@@ -0,0 +1,118 @@
+# bin
+/bin/bash
+/bin/busybox
+
+
+
+# etc
+/etc/config/autossh
+
+/etc/hotplug.d/block/20-sd
+/etc/hotplug.d/iface/20-autossh
+/etc/hotplug.d/iface/30-usb
+/etc/hotplug.d/usb/30-fix_wifi
+/etc/hotplug.d/usb/30-sd
+
+/etc/init.d/atd
+/etc/init.d/autossh
+/etc/init.d/dnsmasq
+/etc/init.d/php7-fpm
+/etc/init.d/pineapd
+/etc/init.d/pineapple
+/etc/init.d/resetssids
+
+/etc/nginx/nginx.conf
+/etc/opkg/customfeeds.conf
+/etc/php7-fpm.d/www.conf
+/etc/pineape
+/etc/pineapple
+
+/etc/rc.button/BTN_1
+/etc/rc.button/reset
+
+/etc/ssh/sshd_config
+/etc/ssl/openssl.cnf
+
+/etc/uci-defaults/90-firewall.sh
+/etc/uci-defaults/91-fstab.sh
+/etc/uci-defaults/92-system.sh
+/etc/uci-defaults/93-pineap.sh
+/etc/uci-defaults/94-reporting.sh
+/etc/uci-defaults/95-network.sh
+/etc/uci-defaults/96-landingpage.sh
+/etc/uci-defaults/97-pineapple.sh
+
+/etc/banner
+/etc/inittab
+/etc/opkg.conf
+/etc/php.ini
+/etc/php7-fpm.conf
+/etc/rc.local
+/etc/shadow
+
+
+
+# lib
+/lib/preinit/30_failsafe_wait
+/lib/preinit/40_run_failsafe_hook
+/lib/upgrade/keep.d/busybox
+/lib/wifi/mac80211.sh
+
+
+
+# pineapple
+/pineapple
+
+
+
+# sbin
+/sbin/fdisk
+/sbin/led
+
+
+
+# usr
+/usr/bin/pineapple
+/usr/bin/pineap
+/usr/bin/uuencode
+
+#/usr/lib/python2.7/encodings
+/usr/lib/libwifi.so
+
+/usr/sbin/http_sniffer
+/usr/sbin/pineapd
+/usr/sbin/resetssids
+
+
+
+# www
+/www
+
+
+
+# Packages
+
+# cc-client
+# libc, libpthread, libstdcpp6, libcurl4, libopenssl1.1, libsqlite3-0, protobuf-lite
+#/usr/lib/libprotobuf-lite.so
+#/usr/lib/libprotobuf-lite.so.15
+#/usr/lib/libprotobuf-lite.so.15.0.1
+#/usr/sbin/C2DISCONNECT
+#/usr/sbin/C2CONNECT
+#/usr/sbin/C2EXFIL
+#/etc/init.d/cc-client
+#/usr/sbin/cc-client
+
+# aircrack-ng-hak5
+# libc, libpcap1, libpcre, libpthread, uclibcxx, libopenssl1.1, libnl-core200, libnl-genl200, zlib
+/usr/lib/libaircrack-osdep-1.5.2.so
+/usr/lib/libaircrack-ce-wpa-1.5.2.so
+/usr/lib/libaircrack-osdep.so
+/usr/lib/libaircrack-ce-wpa.la
+/usr/lib/libaircrack-ce-wpa.so
+/usr/lib/libaircrack-osdep.la
+/usr/bin/aircrack-ng
+/usr/sbin/airmon-ng
+/usr/sbin/airodump-ng-oui-update
+/usr/sbin/aireplay-ng
+/usr/sbin/airodump-ng

+ 112 - 0
lists/tetra.filelist

@@ -0,0 +1,112 @@
+# etc
+/etc/config/autossh
+
+/etc/hotplug.d/block/20-sd
+/etc/hotplug.d/iface/20-autossh
+/etc/hotplug.d/iface/30-usb
+/etc/hotplug.d/usb/30-fix_wifi
+/etc/hotplug.d/usb/30-sd
+
+/etc/init.d/atd
+/etc/init.d/autossh
+/etc/init.d/dnsmasq
+/etc/init.d/php7-fpm
+/etc/init.d/pineapd
+/etc/init.d/pineapple
+/etc/init.d/resetssids
+
+/etc/nginx/nginx.conf
+/etc/opkg/customfeeds.conf
+/etc/php7-fpm.d/www.conf
+/etc/pineape
+/etc/pineapple
+
+/etc/rc.button/BTN_1
+/etc/rc.button/reset
+
+/etc/ssh/sshd_config
+/etc/ssl/openssl.cnf
+
+/etc/uci-defaults/90-firewall.sh
+/etc/uci-defaults/91-fstab.sh
+/etc/uci-defaults/92-system.sh
+/etc/uci-defaults/93-pineap.sh
+/etc/uci-defaults/94-reporting.sh
+/etc/uci-defaults/95-network.sh
+/etc/uci-defaults/96-landingpage.sh
+/etc/uci-defaults/97-pineapple.sh
+
+/etc/banner
+/etc/inittab
+/etc/opkg.conf
+/etc/php.ini
+/etc/php7-fpm.conf
+/etc/rc.local
+/etc/shadow
+
+
+
+# lib
+/lib/preinit/30_failsafe_wait
+/lib/preinit/40_run_failsafe_hook
+/lib/upgrade/keep.d/busybox
+/lib/wifi/mac80211.sh
+
+
+
+# pineapple
+/pineapple
+
+
+
+# sbin
+/sbin/led
+
+
+
+# usr
+/usr/bin/pineapple
+/usr/bin/pineap
+
+/usr/lib/libwifi.so
+
+/usr/sbin/http_sniffer
+/usr/sbin/pineapd
+/usr/sbin/resetssids
+
+# I understand that this was deprecated and deleted since version 2.1.0...
+#/usr/sbin/log_daemon
+
+
+
+# www
+/www
+
+
+
+# Packages
+
+# cc-client
+# libc, libpthread, libstdcpp6, libcurl4, libopenssl1.1, libsqlite3-0, protobuf-lite
+#/usr/lib/libprotobuf-lite.so
+#/usr/lib/libprotobuf-lite.so.15
+#/usr/lib/libprotobuf-lite.so.15.0.1
+#/usr/sbin/C2DISCONNECT
+#/usr/sbin/C2CONNECT
+#/usr/sbin/C2EXFIL
+#/etc/init.d/cc-client
+#/usr/sbin/cc-client
+
+# aircrack-ng-hak5
+# libc, libpcap1, libpcre, libpthread, uclibcxx, libopenssl1.1, libnl-core200, libnl-genl200, zlib
+/usr/lib/libaircrack-osdep-1.5.2.so
+/usr/lib/libaircrack-ce-wpa-1.5.2.so
+/usr/lib/libaircrack-osdep.so
+/usr/lib/libaircrack-ce-wpa.la
+/usr/lib/libaircrack-ce-wpa.so
+/usr/lib/libaircrack-osdep.la
+/usr/bin/aircrack-ng
+/usr/sbin/airmon-ng
+/usr/sbin/airodump-ng-oui-update
+/usr/sbin/aireplay-ng
+/usr/sbin/airodump-ng

+ 112 - 0
lists/universal.filelist

@@ -0,0 +1,112 @@
+# etc
+/etc/config/autossh
+
+/etc/hotplug.d/block/20-sd
+/etc/hotplug.d/iface/20-autossh
+/etc/hotplug.d/iface/30-usb
+/etc/hotplug.d/usb/30-fix_wifi
+/etc/hotplug.d/usb/30-sd
+
+/etc/init.d/atd
+/etc/init.d/autossh
+/etc/init.d/dnsmasq
+/etc/init.d/php7-fpm
+/etc/init.d/pineapd
+/etc/init.d/pineapple
+/etc/init.d/resetssids
+
+/etc/nginx/nginx.conf
+/etc/opkg/customfeeds.conf
+/etc/php7-fpm.d/www.conf
+/etc/pineape
+/etc/pineapple
+
+/etc/rc.button/BTN_1
+/etc/rc.button/reset
+
+/etc/ssh/sshd_config
+/etc/ssl/openssl.cnf
+
+/etc/uci-defaults/90-firewall.sh
+/etc/uci-defaults/91-fstab.sh
+/etc/uci-defaults/92-system.sh
+/etc/uci-defaults/93-pineap.sh
+/etc/uci-defaults/94-reporting.sh
+/etc/uci-defaults/95-network.sh
+/etc/uci-defaults/96-landingpage.sh
+/etc/uci-defaults/97-pineapple.sh
+
+/etc/banner
+/etc/inittab
+/etc/opkg.conf
+/etc/php.ini
+/etc/php7-fpm.conf
+/etc/rc.local
+/etc/shadow
+
+
+
+# lib
+/lib/preinit/30_failsafe_wait
+/lib/preinit/40_run_failsafe_hook
+/lib/upgrade/keep.d/busybox
+/lib/wifi/mac80211.sh
+
+
+
+# pineapple
+/pineapple
+
+
+
+# sbin
+/sbin/led
+
+
+
+# usr
+/usr/bin/pineapple
+/usr/bin/pineap
+
+/usr/lib/libwifi.so
+
+/usr/sbin/http_sniffer
+/usr/sbin/pineapd
+/usr/sbin/resetssids
+
+# I understand that this was deprecated and deleted since version 2.1.0...
+#/usr/sbin/log_daemon
+
+
+
+# www
+/www
+
+
+
+# Packages
+
+# cc-client
+# libc, libpthread, libstdcpp6, libcurl4, libopenssl1.1, libsqlite3-0, protobuf-lite
+#/usr/lib/libprotobuf-lite.so
+#/usr/lib/libprotobuf-lite.so.15
+#/usr/lib/libprotobuf-lite.so.15.0.1
+#/usr/sbin/C2DISCONNECT
+#/usr/sbin/C2CONNECT
+#/usr/sbin/C2EXFIL
+#/etc/init.d/cc-client
+#/usr/sbin/cc-client
+
+# aircrack-ng-hak5
+# libc, libpcap1, libpcre, libpthread, uclibcxx, libopenssl1.1, libnl-core200, libnl-genl200, zlib
+/usr/lib/libaircrack-osdep-1.5.2.so
+/usr/lib/libaircrack-ce-wpa-1.5.2.so
+/usr/lib/libaircrack-osdep.so
+/usr/lib/libaircrack-ce-wpa.la
+/usr/lib/libaircrack-ce-wpa.so
+/usr/lib/libaircrack-osdep.la
+/usr/bin/aircrack-ng
+/usr/sbin/airmon-ng
+/usr/sbin/airodump-ng-oui-update
+/usr/sbin/aireplay-ng
+/usr/sbin/airodump-ng

+ 171 - 0
tools/builder.sh

@@ -0,0 +1,171 @@
+#!/bin/bash
+# by DSR! from https://github.com/xchwarze/wifi-pineapple-cloner
+
+ARCHITECTURE="$1"
+FLAVOR="$2"
+IMAGEBUILDER_FOLDER="$3"
+PROFILE="$4"
+declare -a ARCHITECTURE_TYPES=("mips" "mipsel")
+declare -a FLAVOR_TYPES=("nano" "tetra" "universal")
+if [[ ! -d "$IMAGEBUILDER_FOLDER" || "$PROFILE" == "" ]] || ! grep -q "$ARCHITECTURE" <<< "${ARCHITECTURE_TYPES[*]}" || ! grep -q "$FLAVOR" <<< "${FLAVOR_TYPES[*]}"; then
+    echo "Run with \"builder.sh [ARCHITECTURE] [FLAVOR] [IMAGEBUILDER_FOLDER] [PROFILE]\""
+    echo "    ARCHITECTURE        -> must be one of these values: mips, mipsel"
+    echo "    FLAVOR              -> must be one of these values: nano, tetra, universal"
+    echo "    IMAGEBUILDER_FOLDER -> path to openwrt imagebuilder"
+    echo "    PROFILE             -> profile for use in imagebuilder build"
+
+    exit 1
+fi
+
+# dependencies installed, uninstalled and the order in which they are installed is for a reason!
+# no rtl-sdr, no kmod-usb-net-*, no kmod-rtl8192cu, no kmod-usb-acm
+PACKAGES_NANO="iw at autossh base-files block-mount ca-certificates chat dnsmasq e2fsprogs ethtool firewall hostapd-utils ip6tables iperf3 iwinfo kmod-crypto-manager kmod-fs-ext4 kmod-fs-nfs kmod-fs-vfat kmod-gpio-button-hotplug kmod-ipt-offload kmod-leds-gpio kmod-ledtrig-default-on kmod-ledtrig-netdev kmod-ledtrig-timer kmod-mt76x2u kmod-nf-nathelper kmod-rt2800-usb kmod-rtl8187 kmod-scsi-generic kmod-usb-ohci kmod-usb-storage-extras kmod-usb-uhci kmod-usb2 libbz2-1.0 libcurl4 libelf1 libffi libgmp10 libiconv-full2 libintl libltdl7 libnet-1.2.x libnl200 libreadline8 libustream-mbedtls20150806 libxml2 logd macchanger mtd nano ncat netcat nginx openssh-client openssh-server openssh-sftp-server openssl-util php7-fpm php7-mod-hash php7-mod-json php7-mod-mbstring php7-mod-session php7-mod-sqlite3 ppp ppp-mod-pppoe procps-ng-pkill procps-ng-ps python-logging python-openssl python-sqlite3 ssmtp tcpdump-mini uci uclibcxx uclient-fetch urandom-seed urngd usb-modeswitch usbreset usbutils wget wireless-tools wpad busybox libatomic1 libstdcpp6 -wpad-basic -dropbear -swconfig -odhcpd-ipv6only -odhcp6c"
+
+# no rtl-sdr, no kmod-usb-net-*, no kmod-usb-serial-*, no kmod-rtl8192cu, no kmod-usb-acm, no kmod-usb-wdm, no kmod-lib-crc-itu-t
+PACKAGES_TETRA="iw at autossh base-files bash block-mount ca-certificates chat dnsmasq e2fsprogs ethtool firewall hostapd-utils ip6tables iwinfo kmod-crypto-manager kmod-fs-ext4 kmod-fs-nfs kmod-fs-vfat kmod-gpio-button-hotplug kmod-ipt-offload kmod-leds-gpio kmod-ledtrig-default-on kmod-ledtrig-netdev kmod-ledtrig-timer kmod-mt76x2u kmod-nf-nathelper kmod-rt2800-usb kmod-rtl8187 kmod-scsi-generic kmod-usb-ohci kmod-usb-storage-extras kmod-usb-uhci kmod-usb2 libbz2-1.0 libcurl4 libelf1 libffi libgdbm libgmp10 libiconv-full2 libltdl7 libnet-1.2.x libnl200 libustream-mbedtls20150806 libxml2 logd macchanger mtd nano ncat netcat nginx openssh-client openssh-server openssh-sftp-server openssl-util php7-fpm php7-mod-hash php7-mod-json php7-mod-mbstring php7-mod-session php7-mod-sqlite3 ppp ppp-mod-pppoe procps-ng-pkill procps-ng-ps python-logging python-openssl python-sqlite3 ssmtp tcpdump-mini uci uclibcxx uclient-fetch urandom-seed urngd usb-modeswitch usbreset usbutils wget wireless-tools wpad busybox libatomic1 libstdcpp6 -wpad-basic -dropbear -odhcp6c -odhcpd-ipv6only"
+
+# if you don't install a custom build of busybox you have to install fdisk
+# no rtl-sdr, no kmod-usb-net-*, no kmod-usb-serial-*, no kmod-rtl8192cu, no kmod-usb-acm, no kmod-usb-wdm, no kmod-lib-crc-itu-t, no ppp*, no python-*
+PACKAGES_UNIVERSAL="iw at autossh base-files bash block-mount ca-certificates chat dnsmasq e2fsprogs ethtool firewall hostapd-utils ip6tables iwinfo kmod-crypto-manager kmod-fs-ext4 kmod-fs-nfs kmod-fs-vfat kmod-gpio-button-hotplug kmod-ipt-offload kmod-leds-gpio kmod-ledtrig-default-on kmod-ledtrig-netdev kmod-ledtrig-timer kmod-mt76x2u kmod-nf-nathelper kmod-rt2800-usb kmod-rtl8187 kmod-scsi-generic kmod-usb-ohci kmod-usb-storage-extras kmod-usb-uhci kmod-usb2 libbz2-1.0 libcurl4 libelf1 libffi libgdbm libgmp10 libiconv-full2 libltdl7 libnet-1.2.x libnl200 libustream-mbedtls20150806 libxml2 logd macchanger mtd nano ncat netcat nginx openssh-client openssh-server openssh-sftp-server openssl-util php7-fpm php7-mod-hash php7-mod-json php7-mod-mbstring php7-mod-session php7-mod-sqlite3 procps-ng-pkill procps-ng-ps ssmtp tcpdump-mini uci uclibcxx uclient-fetch urandom-seed urngd usb-modeswitch usbreset usbutils wget wireless-tools wpad busybox libatomic1 libstdcpp6 -wpad-basic -dropbear -odhcpd-ipv6only -ppp -ppp-mod-pppoe"
+
+# add missing deps and custom busybox build
+declare -a FORCE_PACKAGES=("libubus20191227_2019-12-27-041c9d1c-1" "busybox_1.30.1-6")
+
+IMAGEBUILDER_FOLDER="$(realpath $IMAGEBUILDER_FOLDER)"
+TOOL_FOLDER="$(realpath $(dirname $0)/../tools)"
+BUILD_FOLDER="$(realpath $(dirname $0)/../build)"
+
+
+
+# steps
+prepare_builder () {
+    echo "[*] Prepare builder"
+    echo "******************************"
+    echo ""
+
+    PACKAGES_ARQ="${ARCHITECTURE}_24kc"
+    DOWNLOAD_BASE_URL="https://github.com/xchwarze/wifi-pineapple-community/raw/main/packages/experimental"
+
+    for TARGET in ${FORCE_PACKAGES[@]}; do
+        PACKAGE_IPK="${TARGET}_${PACKAGES_ARQ}.ipk"
+        PACKAGE_PATH="$IMAGEBUILDER_FOLDER/packages/$PACKAGE_IPK"
+        if [ ! -f "$PACKAGE_PATH" ]; then
+            echo "[+] Install: $TARGET"
+            wget -q "$DOWNLOAD_BASE_URL/$PACKAGES_ARQ/$PACKAGE_IPK" -O "$PACKAGE_PATH"
+        else
+            echo "[+] Already exist: $TARGET"
+        fi
+    done
+
+    echo "[+] Builder setup complete"
+    echo ""
+}
+
+prepare_build () {
+    echo "[*] Prepare build"
+    echo "******************************"
+    echo ""
+
+    # clean
+    rm -rf _basefw.* basefw.bin
+    rm -rf "$BUILD_FOLDER"
+    mkdir -p "$BUILD_FOLDER/release"
+
+    # get target firmware
+    # this work only with lastest binwalk version!
+    if [[ "$FLAVOR" == "tetra" || "$FLAVOR" == "universal" ]]; then
+        echo "[+] Downloading TETRA firmware..."
+        wget -q https://github.com/xchwarze/wifi-pineapple-community/raw/main/firmwares/2.7.0-tetra.bin -O basefw.bin
+        
+        echo "[+] Unpack firmware for get file system"
+        binwalk basefw.bin -e 
+        binwalk _basefw.bin.extracted/sysupgrade-pineapple-tetra/root -e --preserve-symlinks
+        mv _basefw.bin.extracted/sysupgrade-pineapple-tetra/_root.extracted/squashfs-root/ "$BUILD_FOLDER/rootfs-base"
+    else
+        echo "[+] Downloading NANO firmware..."
+        wget -q https://github.com/xchwarze/wifi-pineapple-community/raw/main/firmwares/2.7.0-nano.bin -O basefw.bin
+
+        echo "[+] Unpack firmware for get file system"
+        binwalk basefw.bin -e --preserve-symlinks
+        mv _basefw.bin.extracted/squashfs-root/ "$BUILD_FOLDER/rootfs-base"
+    fi
+
+    rm -rf _basefw.* basefw.bin
+    #sudo chmod +x "$TOOL_FOLDER/*.sh"
+
+    echo "[+] Copying the original files"
+    "$TOOL_FOLDER/copier.sh" "$TOOL_FOLDER/../lists/$FLAVOR.filelist" "$BUILD_FOLDER/rootfs-base" "$BUILD_FOLDER/rootfs"
+    if [ $? -ne 0 ]; then
+        echo "[!] An error occurred while copying the original files. Check the log for errors."
+        exit 1
+    fi
+
+    echo "[+] Patch file system"
+    "$TOOL_FOLDER/fs-patcher.sh" "$ARCHITECTURE" "$FLAVOR" "$BUILD_FOLDER/rootfs"
+    if [ $? -ne 0 ]; then
+        echo "[!] An error occurred during the execution of the process. Check the log for errors."
+        exit 1
+    fi
+
+    rm -rf "$BUILD_FOLDER/rootfs-base"
+    echo ""
+}
+
+build () {
+    echo "[*] Build"
+    echo "******************************"
+    echo ""
+
+    # clean
+    echo "[+] Clean last build data"
+    #make clean
+    rm -rf "$IMAGEBUILDER_FOLDER/tmp/"
+    rm -rf "$IMAGEBUILDER_FOLDER/build_dir/target-*/root*"
+    rm -rf "$IMAGEBUILDER_FOLDER/build_dir/target-*/json_*"
+    rm -rf "$IMAGEBUILDER_FOLDER/bin/targets/*"
+
+    # set selected packages
+    echo "[+] Executing make"
+    selected_packages="$PACKAGES_UNIVERSAL"
+    if [[ "$FLAVOR" == "nano" ]];
+    then
+        selected_packages="$PACKAGES_NANO"
+    elif [[ "$FLAVOR" == "tetra" ]];
+    then
+        selected_packages="$PACKAGES_TETRA"
+    fi
+
+    # build
+    cd "$IMAGEBUILDER_FOLDER"
+    make image PROFILE="$1" PACKAGES="$selected_packages" FILES="$BUILD_FOLDER/rootfs" BIN_DIR="$BUILD_FOLDER/release" > "$BUILD_FOLDER/release/make.log"
+    if [ $? -ne 0 ]; then
+        echo ""
+        echo "[!] An error occurred in the build process. Check file release/make.log for more information."
+        exit 1
+    fi
+
+    # add this second check for build process
+    checkFwFileExist=$(ls "$BUILD_FOLDER/release"/*-sysupgrade.* 2>/dev/null | wc -l)
+    if [ $checkFwFileExist -eq 0 ]; then
+        echo ""
+        echo "[!] OpenWRT finished the build process but no firmware was found. Check the release/make.log to see if the process was completed correctly."
+        #exit 1
+    fi
+    echo ""
+}
+
+
+
+# implement this shitty logic
+echo "Wifi Pineapple Cloner - builder"
+echo "************************************** by DSR!"
+echo ""
+
+prepare_builder
+prepare_build
+build "$PROFILE"
+
+echo "[*] Firmware folder: $BUILD_FOLDER/release"
+echo "******************************"
+ls -l "$BUILD_FOLDER/release"
+echo ""

+ 72 - 0
tools/copier.sh

@@ -0,0 +1,72 @@
+#!/bin/bash
+# by DSR! from https://github.com/xchwarze/wifi-pineapple-cloner
+
+FILE_LIST="$1"
+FROM_FOLDER="$2"
+TO_FOLDER="$3"
+COUNTER=0
+if [[ ! -f "$FILE_LIST" || ! -d "$FROM_FOLDER" || "$TO_FOLDER" == "" ]]; then
+    echo "Run with \"copier.sh [FILE_LIST] [FROM_FOLDER] [TO_FOLDER]\""
+    echo "    FILE_LIST   -> flavor file list"
+    echo "    FROM_FOLDER -> path to base fs"
+    echo "    TO_FOLDER   -> path to new fs"
+
+    exit 1
+fi
+
+
+
+FILE_LIST="$(realpath $FILE_LIST)"
+FROM_FOLDER="$(realpath $FROM_FOLDER)"
+TO_FOLDER="$(realpath $TO_FOLDER)"
+
+echo "Filelist2Copy - by DSR!"
+echo "******************************"
+echo ""
+
+echo "[*] Start copy loop"
+rm -rf "$TO_FOLDER"
+mkdir "$TO_FOLDER"
+
+for FILE in $(cat "$FILE_LIST")
+do
+    if [[ "${FILE:0:1}" != '/' ]]; then
+        continue
+    fi
+    
+    # fix name chars
+    FILE=$(echo $FILE | sed $'s/\r//')
+
+    # check exist
+    if [[ ! -f "$FROM_FOLDER$FILE" ]] && [[ ! -d "$FROM_FOLDER$FILE" ]]; then
+        echo "[!] File does not exist: ${FROM_FOLDER}${FILE}"
+        continue
+    fi
+
+    # check file type
+    #TYPE_CHECK=$(file "$FROM_FOLDER$FILE" | grep "ELF")
+    #if [[ $TYPE_CHECK != "" ]]; then
+    #    echo "[+] ELF: $FILE"
+    #    continue
+    #fi
+
+    let COUNTER++
+
+    FOLDER=$(dirname $FILE)
+    mkdir -p "$TO_FOLDER$FOLDER"
+
+    # if folder...
+    if [[ -d "$FROM_FOLDER$FILE" ]]; then
+        cp -R "$FROM_FOLDER$FILE" "$TO_FOLDER$FILE"
+    else
+        cp -P "$FROM_FOLDER$FILE" "$TO_FOLDER$FILE"
+    fi
+done
+
+if [ $COUNTER -eq 0 ]; then
+    echo "[!] No files were copied. Verify that the paths are correct."
+    exit 1
+fi
+
+echo "[+] Files copied: $COUNTER"
+echo ""

+ 103 - 0
tools/dependencies-install.sh

@@ -0,0 +1,103 @@
+#!/bin/bash
+# by DSR! from https://github.com/xchwarze/wifi-pineapple-cloner
+
+OPENWRT_VERSION="19.07.7"
+OPENWRT_BASE_URL="https://downloads.openwrt.org/releases/$OPENWRT_VERSION/targets"
+declare -a OPENWRT_MIPS_TARGET_LIST=(
+    "ar71xx-generic" "ar71xx-nand" "ath79-generic" "lantiq-xrx200"
+)
+declare -a OPENWRT_MIPSEL_TARGET_LIST=(
+    "ramips-mt7620" "ramips-mt7621" "ramips-mt76x8"
+)
+
+install_openwrt_deps () {
+    TARGET="$1"
+
+    FOLDER_NAME="imagebuilder-$OPENWRT_VERSION-$TARGET"
+    ORIGINAL_FOLDER_NAME="openwrt-imagebuilder-$OPENWRT_VERSION-$TARGET.Linux-x86_64"
+    FILE="$FOLDER_NAME.tar.xz"
+
+    # download imagebuilder
+    if [ ! -d "$FOLDER_NAME" ]; then
+        if [ ! -f "$FILE" ]; then
+            echo "    [+] Downloading imagebuilder..."
+            TYPE=$(echo $TARGET | sed "s/-/\//g")
+            wget -q "$OPENWRT_BASE_URL/$TYPE/$ORIGINAL_FOLDER_NAME.tar.xz" -O "$FILE"
+        fi
+
+        # install...
+        echo "    [+] Install imagebuilder..."
+        rm -rf "$FOLDER_NAME"
+        tar xJf "$FILE"
+        mv "$ORIGINAL_FOLDER_NAME" "$FOLDER_NAME"
+
+        # correct opkg feeds
+        echo "    [+] Correct opkg feeds"
+        sed -i "s/src\/gz openwrt_freifunk/#/" "$FOLDER_NAME/repositories.conf"
+        sed -i "s/src\/gz openwrt_luci/#/" "$FOLDER_NAME/repositories.conf"
+        sed -i "s/src\/gz openwrt_telephony/#/" "$FOLDER_NAME/repositories.conf"
+    fi
+}
+
+install_ubuntu_deps () {
+    echo "Install ubuntu deps..."
+    echo "******************************"
+
+    # install deps openwrt make and others
+    apt-get install build-essential python2 wget gawk libncurses5-dev libncursesw5-dev zip rename -y
+
+    # install binwalk
+    git clone https://github.com/ReFirmLabs/binwalk
+    cd binwalk && sudo python3 setup.py install && sudo ./deps.sh
+
+    echo ""
+    echo "[*] Install script end!"
+}
+
+install_openwrt_deps_mips () {
+    echo "Install OpenWrt MIPS deps..."
+    echo "******************************"
+
+    for TARGET in ${OPENWRT_MIPS_TARGET_LIST[@]}; do
+        echo "[*] Install: $TARGET"
+        install_openwrt_deps $TARGET
+    done
+
+    echo ""
+    echo "[*] Install script end!"
+}
+
+install_openwrt_deps_mipsel () {
+    echo "Install OpenWrt MIPSEL deps..."
+    echo "******************************"
+
+    for TARGET in ${OPENWRT_MIPSEL_TARGET_LIST[@]}; do
+        echo "[*] Install: $TARGET"
+        install_openwrt_deps $TARGET
+    done
+
+    echo ""
+    echo "[*] Install script end!"
+}
+
+
+
+echo "Wifi Pineapple Cloner - dependencies"
+echo "************************************** by DSR!"
+echo ""
+
+if [ "$1" == "openwrt-deps-mips" ]
+then
+    install_openwrt_deps_mips
+elif [ "$1" == "openwrt-deps-mipsel" ]
+then
+    install_openwrt_deps_mipsel
+elif [ "$1" == "ubuntu-deps" ]
+then
+    install_ubuntu_deps
+else
+    echo "Valid command:"
+    echo "openwrt-deps-mips    -> install imagebuilders for mips and configure it"
+    echo "openwrt-deps-mipsel  -> install imagebuilders for mipsel and configure it"
+    echo "ubuntu-deps          -> install ubuntu dependencies"
+fi

+ 291 - 0
tools/fs-patcher.sh

@@ -0,0 +1,291 @@
+#!/bin/bash
+# by DSR! from https://github.com/xchwarze/wifi-pineapple-cloner
+
+ARCHITECTURE="$1"
+FLAVOR="$2"
+ROOT_FS="$3"
+declare -a ARCHITECTURE_TYPES=("mips" "mipsel")
+declare -a FLAVOR_TYPES=("nano" "tetra" "universal")
+if [[ ! -d "$ROOT_FS" ]] || ! grep -q "$ARCHITECTURE" <<< "${ARCHITECTURE_TYPES[*]}" || ! grep -q "$FLAVOR" <<< "${FLAVOR_TYPES[*]}"; then
+    echo "Run with \"fs-patcher.sh [ARCHITECTURE] [FLAVOR] [FS_FOLDER]\""
+    echo "    ARCHITECTURE  -> must be one of these values: mips, mipsel"
+    echo "    FLAVOR        -> must be one of these values: nano, tetra, universal"
+    echo "    FS_FOLDER     -> folder containing the fs to use"
+
+    exit 1
+fi
+
+ROOT_FS="$(realpath $ROOT_FS)"
+FILES_FOLDER="$(realpath $(dirname $0)/../files)"
+
+
+
+common_patch () {
+    echo "[*] Device detection fix"
+
+    # fix "unknown operand" error
+    sed -i 's/print $6/print $1/' "$ROOT_FS/etc/hotplug.d/block/20-sd"
+    sed -i 's/print $6/print $1/' "$ROOT_FS/etc/hotplug.d/usb/30-sd"
+    sed -i 's/print $6/print $1/' "$ROOT_FS/etc/init.d/pineapple"
+    sed -i 's/print $6/print $1/' "$ROOT_FS/etc/rc.button/BTN_1"
+    sed -i 's/print $6/print $1/' "$ROOT_FS/etc/rc.button/reset"
+    sed -i 's/print $6/print $1/' "$ROOT_FS/etc/rc.local"
+    sed -i 's/print $6/print $1/' "$ROOT_FS/etc/uci-defaults/90-firewall.sh"
+    sed -i 's/print $6/print $1/' "$ROOT_FS/etc/uci-defaults/91-fstab.sh"
+    sed -i 's/print $6/print $1/' "$ROOT_FS/etc/uci-defaults/92-system.sh"
+    sed -i 's/print $6/print $1/' "$ROOT_FS/etc/uci-defaults/95-network.sh"
+    sed -i 's/print $6/print $1/' "$ROOT_FS/etc/uci-defaults/97-pineapple.sh"
+    sed -i 's/print $6/print $1/' "$ROOT_FS/sbin/led"
+
+    # force setup
+    sed -i 's/..Get Device/device="NANO"/' "$ROOT_FS/etc/rc.button/BTN_1"
+    sed -i 's/..Get Device/device="NANO"/' "$ROOT_FS/etc/rc.button/reset"
+    sed -i 's/..Get Device/device="NANO"/' "$ROOT_FS/etc/rc.local"
+    sed -i 's/..Get Version and Device/device="TETRA"/' "$ROOT_FS/etc/uci-defaults/90-firewall.sh"
+    sed -i 's/..Get Version and Device/device="NANO"/' "$ROOT_FS/etc/uci-defaults/91-fstab.sh"
+    sed -i 's/..Get Version and Device/device="NANO"/' "$ROOT_FS/etc/uci-defaults/95-network.sh"
+    sed -i 's/..Get Version and Device/device="NANO"/' "$ROOT_FS/etc/uci-defaults/97-pineapple.sh"
+    sed -i 's/..Get device type/device="NANO"/' "$ROOT_FS/etc/uci-defaults/92-system.sh"
+    #sed -i 's/..led (C) Hak5 2018/device="NANO"/' "$ROOT_FS/sbin/led"
+
+
+    echo "[*] Correct OPKG feed url"
+
+    cp "$FILES_FOLDER/$ARCHITECTURE/customfeeds.conf" "$ROOT_FS/etc/opkg/customfeeds.conf"
+
+
+    echo "[*] Pineap"
+
+    cp "$FILES_FOLDER/$ARCHITECTURE/pineap/pineapd" "$ROOT_FS/usr/sbin/pineapd"
+    cp "$FILES_FOLDER/$ARCHITECTURE/pineap/pineap" "$ROOT_FS/usr/bin/pineap"
+    cp "$FILES_FOLDER/$ARCHITECTURE/pineap/resetssids" "$ROOT_FS/usr/sbin/resetssids"
+    cp "$FILES_FOLDER/$ARCHITECTURE/pineap/libwifi.so" "$ROOT_FS/usr/lib/libwifi.so"
+    chmod +x "$ROOT_FS/usr/sbin/pineapd"
+    chmod +x "$ROOT_FS/usr/bin/pineap"
+    chmod +x "$ROOT_FS/usr/sbin/resetssids"
+    chmod +x "$ROOT_FS/usr/lib/libwifi.so"
+
+
+    echo "[*] Add Karma support"
+
+    mkdir -p "$ROOT_FS/lib/netifd/wireless"
+    cp "$FILES_FOLDER/common/karma/mac80211.sh" "$ROOT_FS/lib/netifd/wireless/mac80211.sh"
+    cp "$FILES_FOLDER/common/karma/hostapd.sh" "$ROOT_FS/lib/netifd/hostapd.sh"
+    cp "$FILES_FOLDER/$ARCHITECTURE/karma/hostapd_cli" "$ROOT_FS/usr/sbin/hostapd_cli"
+    cp "$FILES_FOLDER/$ARCHITECTURE/karma/wpad" "$ROOT_FS/usr/sbin/wpad"
+    chmod +x "$ROOT_FS/lib/netifd/wireless/mac80211.sh"
+    chmod +x "$ROOT_FS/lib/netifd/hostapd.sh"
+    chmod +x "$ROOT_FS/usr/sbin/hostapd_cli"
+    chmod +x "$ROOT_FS/usr/sbin/wpad"
+
+
+    echo "[*] Install panel fixes and improvements"
+
+    # update panel code
+    rm -rf "$ROOT_FS/pineapple"
+    wget -q https://github.com/xchwarze/wifi-pineapple-panel/archive/refs/heads/wpc.zip -O updated-panel.zip
+    unzip -q updated-panel.zip
+
+    cp -r wifi-pineapple-panel-wpc/src/* "$ROOT_FS/"
+    rm -rf wifi-pineapple-panel-wpc updated-panel.zip
+
+    chmod +x "$ROOT_FS/etc/init.d/pineapd"
+    chmod +x "$ROOT_FS/etc/uci-defaults/93-pineap.sh"
+    chmod +x "$ROOT_FS/pineapple/modules/Advanced/formatSD/format_sd"
+    chmod +x "$ROOT_FS/pineapple/modules/Help/files/debug"
+    chmod +x "$ROOT_FS/pineapple/modules/PineAP/executable/executable"
+    chmod +x "$ROOT_FS/pineapple/modules/Reporting/files/reporting"
+
+    cp "$FILES_FOLDER/common/pineapple/favicon.ico" "$ROOT_FS/pineapple/img/favicon.ico"
+    cp "$FILES_FOLDER/common/pineapple/favicon-16x16.png" "$ROOT_FS/pineapple/img/favicon-16x16.png"
+    cp "$FILES_FOLDER/common/pineapple/favicon-32x32.png" "$ROOT_FS/pineapple/img/favicon-32x32.png"
+
+    # fix docs size
+    truncate -s 0 "$ROOT_FS/pineapple/modules/Setup/eula.txt"
+    truncate -s 0 "$ROOT_FS/pineapple/modules/Setup/license.txt"
+
+
+    echo "[*] Enable ssh by default"
+
+    sed -i 's/\/etc\/init.d\/sshd/#\/etc\/init.d\/sshd/' "$ROOT_FS/etc/rc.local"
+
+
+    echo "[*] Change root password to: root"
+
+    cp "$FILES_FOLDER/common/etc/shadow" "$ROOT_FS/etc/shadow"
+
+
+    echo "[*] Fix uci-defaults"
+
+    cp "$FILES_FOLDER/common/etc/92-system.sh" "$ROOT_FS/etc/uci-defaults/92-system.sh"
+    cp "$FILES_FOLDER/common/etc/95-network.sh" "$ROOT_FS/etc/uci-defaults/95-network.sh"
+    cp "$FILES_FOLDER/common/etc/97-pineapple.sh" "$ROOT_FS/etc/uci-defaults/97-pineapple.sh"
+
+
+    echo "[*] Fix pendrive hotplug"
+
+    cp "$FILES_FOLDER/common/etc/20-sd-universal" "$ROOT_FS/etc/hotplug.d/block/20-sd-universal"
+    rm "$ROOT_FS/etc/hotplug.d/block/20-sd"
+    rm "$ROOT_FS/etc/hotplug.d/usb/30-sd"
+
+
+    echo "[*] Add support for reflash"
+
+    mkdir -p "$ROOT_FS/lib/upgrade/keep.d"
+    cp "$FILES_FOLDER/common/lib/pineapple.keep" "$ROOT_FS/lib/upgrade/keep.d/pineapple"
+
+
+    echo "[*] Fix airmon-ng listInterfaces()"
+
+    mkdir -p "$ROOT_FS/usr/sbin"
+    cp "$FILES_FOLDER/common/usr/airmon-ng" "$ROOT_FS/usr/sbin/airmon-ng"
+    chmod +x "$ROOT_FS/usr/sbin/airmon-ng"
+
+
+    echo "[*] Add wpc-tools and service"
+
+    cp "$FILES_FOLDER/common/etc/wpc-tools" "$ROOT_FS/etc/init.d/wpc-tools"
+    cp "$FILES_FOLDER/common/usr/wpc-tools" "$ROOT_FS/usr/bin/wpc-tools"
+    chmod +x "$ROOT_FS/etc/init.d/wpc-tools"
+    chmod +x "$ROOT_FS/usr/bin/wpc-tools"
+
+
+    echo "[*] Other fixs"
+
+    # clean files
+    rm -f "$ROOT_FS/etc/pineapple/changes"
+    rm -f "$ROOT_FS/etc/pineapple/pineapple_version"
+
+    # default wifi config
+    cp "$FILES_FOLDER/common/lib/mac80211.sh" "$ROOT_FS/lib/wifi/mac80211.sh"
+
+    # fix wifi detection
+    cp "$FILES_FOLDER/common/etc/30-fix_wifi" "$ROOT_FS/etc/hotplug.d/usb/30-fix_wifi"
+
+    # copy clean version of led script
+    cp "$FILES_FOLDER/common/sbin/led" "$ROOT_FS/sbin/led"
+    chmod +x "$ROOT_FS/sbin/led"
+
+    # add setup support for routers that do not have a reset button but do have wps
+    # this modified the package "hostapd-common" wps button script
+    mkdir -p "$ROOT_FS/etc/rc.button"
+    cp "$FILES_FOLDER/common/etc/wps" "$ROOT_FS/etc/rc.button/wps"
+    chmod +x "$ROOT_FS/etc/rc.button/wps"
+
+    # add new banner
+    cp "$FILES_FOLDER/common/etc/banner" "$ROOT_FS/etc/banner"
+}
+
+mipsel_patch () {
+    echo "[*] Add mipsel support"
+    
+    cp "$FILES_FOLDER/$ARCHITECTURE/aircrack/aircrack-ng" "$ROOT_FS/usr/bin/aircrack-ng"
+    cp "$FILES_FOLDER/$ARCHITECTURE/aircrack/aireplay-ng" "$ROOT_FS/usr/sbin/aireplay-ng"
+    cp "$FILES_FOLDER/$ARCHITECTURE/aircrack/airodump-ng" "$ROOT_FS/usr/sbin/airodump-ng"
+    cp "$FILES_FOLDER/$ARCHITECTURE/aircrack/airodump-ng-oui-update" "$ROOT_FS/usr/sbin/airodump-ng-oui-update"
+    cp "$FILES_FOLDER/$ARCHITECTURE/aircrack/libaircrack-osdep-1.5.2.so" "$ROOT_FS/usr/lib/libaircrack-osdep-1.5.2.so"
+    cp "$FILES_FOLDER/$ARCHITECTURE/aircrack/libaircrack-ce-wpa-1.5.2.so" "$ROOT_FS/usr/lib/libaircrack-ce-wpa-1.5.2.so"
+    cp "$FILES_FOLDER/$ARCHITECTURE/aircrack/libaircrack-osdep.so" "$ROOT_FS/usr/lib/libaircrack-osdep.so"
+    cp "$FILES_FOLDER/$ARCHITECTURE/aircrack/libaircrack-ce-wpa.la" "$ROOT_FS/usr/lib/libaircrack-ce-wpa.la"
+    cp "$FILES_FOLDER/$ARCHITECTURE/aircrack/libaircrack-ce-wpa.so" "$ROOT_FS/usr/lib/libaircrack-ce-wpa.so"
+    cp "$FILES_FOLDER/$ARCHITECTURE/aircrack/libaircrack-osdep.la" "$ROOT_FS/usr/lib/libaircrack-osdep.la"
+    chmod +x "$ROOT_FS/usr/bin/aircrack-ng"
+    chmod +x "$ROOT_FS/usr/sbin/aireplay-ng"
+    chmod +x "$ROOT_FS/usr/sbin/airodump-ng"
+    chmod +x "$ROOT_FS/usr/sbin/airodump-ng-oui-update"
+    chmod +x "$ROOT_FS/usr/lib/libaircrack-osdep-1.5.2.so"
+    chmod +x "$ROOT_FS/usr/lib/libaircrack-ce-wpa-1.5.2.so"
+    chmod +x "$ROOT_FS/usr/lib/libaircrack-osdep.so"
+    chmod +x "$ROOT_FS/usr/lib/libaircrack-ce-wpa.la"
+    chmod +x "$ROOT_FS/usr/lib/libaircrack-ce-wpa.so"
+    chmod +x "$ROOT_FS/usr/lib/libaircrack-osdep.la"
+
+    cp "$FILES_FOLDER/$ARCHITECTURE/others/http_sniffer" "$ROOT_FS/usr/sbin/http_sniffer"
+    chmod +x "$ROOT_FS/usr/sbin/http_sniffer"
+}
+
+nano_patch () {
+    # correct python-codecs version (from python-codecs_2.7.18-3_mips_24kc.ipk)
+    mkdir -p "$ROOT_FS/usr/lib/python2.7/encodings"
+    cp "$FILES_FOLDER/$ARCHITECTURE/python/encodings/__init__.pyc" "$ROOT_FS/usr/lib/python2.7/encodings/__init__.pyc"
+    cp "$FILES_FOLDER/$ARCHITECTURE/python/encodings/aliases.pyc" "$ROOT_FS/usr/lib/python2.7/encodings/aliases.pyc"
+    cp "$FILES_FOLDER/$ARCHITECTURE/python/encodings/base64_codec.pyc" "$ROOT_FS/usr/lib/python2.7/encodings/base64_codec.pyc"
+    cp "$FILES_FOLDER/$ARCHITECTURE/python/encodings/hex_codec.pyc" "$ROOT_FS/usr/lib/python2.7/encodings/hex_codec.pyc"
+
+    # panel changes
+    # sed -i "s/\$data = file_get_contents('\/proc\/cpuinfo')/return 'nano'/" "$ROOT_FS/pineapple/api/pineapple.php"
+    cp "$FILES_FOLDER/common/pineapple/config.php.nano" "$ROOT_FS/pineapple/config.php"
+
+    # other changes
+    sed -i "s/exec(\"cat \/proc\/cpuinfo | grep 'machine'\")/'nano'/" "$ROOT_FS/usr/bin/pineapple/site_survey"
+
+    # fix banner info
+    sed -i 's/DEVICE/NANO/' "$ROOT_FS/etc/banner"
+}
+
+tetra_patch () {
+    # correct python-codecs version (from python-codecs_2.7.18-3_mips_24kc.ipk)
+    mkdir -p "$ROOT_FS/usr/lib/python2.7/encodings"
+    cp "$FILES_FOLDER/$ARCHITECTURE/python/encodings/__init__.pyc" "$ROOT_FS/usr/lib/python2.7/encodings/__init__.pyc"
+    cp "$FILES_FOLDER/$ARCHITECTURE/python/encodings/aliases.pyc" "$ROOT_FS/usr/lib/python2.7/encodings/aliases.pyc"
+    cp "$FILES_FOLDER/$ARCHITECTURE/python/encodings/base64_codec.pyc" "$ROOT_FS/usr/lib/python2.7/encodings/base64_codec.pyc"
+    cp "$FILES_FOLDER/$ARCHITECTURE/python/encodings/hex_codec.pyc" "$ROOT_FS/usr/lib/python2.7/encodings/hex_codec.pyc"
+
+    # panel changes
+    # sed -i 's/tetra/nulled/' "$ROOT_FS/pineapple/js/directives.js"
+    # sed -i 's/tetra/nulled/' "$ROOT_FS/pineapple/modules/ModuleManager/js/module.js"
+    # sed -i 's/tetra/nulled/' "$ROOT_FS/pineapple/modules/Advanced/module.html"
+    # sed -i 's/nano/tetra/' "$ROOT_FS/pineapple/html/install-modal.html"
+    # sed -i 's/nano/tetra/' "$ROOT_FS/pineapple/modules/Advanced/module.html"
+    # sed -i 's/nano/tetra/' "$ROOT_FS/pineapple/modules/ModuleManager/js/module.js"
+    # sed -i 's/nano/tetra/' "$ROOT_FS/pineapple/modules/Reporting/js/module.js"
+    # sed -i 's/nano/tetra/' "$ROOT_FS/pineapple/modules/Reporting/api/module.php"
+    # sed -i "s/\$data = file_get_contents('\/proc\/cpuinfo')/return 'tetra'/" "$ROOT_FS/pineapple/api/pineapple.php"
+    cp "$FILES_FOLDER/common/pineapple/config.php.tetra" "$ROOT_FS/pineapple/config.php"
+
+    # other changes
+    sed -i "s/exec(\"cat \/proc\/cpuinfo | grep 'machine'\")/'tetra'/" "$ROOT_FS/usr/bin/pineapple/site_survey"
+
+    # fix banner info
+    sed -i 's/DEVICE/TETRA/' "$ROOT_FS/etc/banner"
+}
+
+universal_patch () {
+    # panel changes
+    cp "$FILES_FOLDER/common/pineapple/config.php.tetra" "$ROOT_FS/pineapple/config.php"
+
+    # other changes
+    sed -i "s/exec(\"cat \/proc\/cpuinfo | grep 'machine'\")/'tetra'/" "$ROOT_FS/usr/bin/pineapple/site_survey"
+
+    # fix banner info
+    sed -i 's/DEVICE/OMEGA/' "$ROOT_FS/etc/banner"
+}
+
+
+
+# implement....
+echo "Wifi Pineapple Cloner v4"
+echo "by DSR!"
+echo "******************************"
+echo ""
+
+# apply patches in order
+common_patch
+if [[ "$ARCHITECTURE" == "mipsel" ]]; then
+    mipsel_patch
+fi
+
+echo "[*] Setting target as: $FLAVOR"
+if [[ $FLAVOR = 'nano' ]]
+then
+    nano_patch
+elif [[ $FLAVOR = 'tetra' ]]
+then
+    tetra_patch
+elif [[ $FLAVOR = 'universal' ]]
+then
+    universal_patch
+fi
+
+echo "[*] Done!"
+echo ""

+ 159 - 0
tools/opkg-parser.php

@@ -0,0 +1,159 @@
+<?php 
+# by DSR! from https://github.com/xchwarze/wifi-pineapple-cloner
+
+error_reporting(E_ALL);
+
+if (!isset($_SERVER['argv']) && !isset($argv)) {
+    echo "Please enable the register_argc_argv directive in your php.ini\n";
+    exit(1);
+} elseif (!isset($argv)) {
+    $argv = $_SERVER['argv'];
+}
+
+if (!isset($argv[1])) {
+    echo "Run with \"php opkg-parser.php [PATH] [DIFF_SEPARATOR]\"\n";
+    echo "    PATH           -> path to opkg status file\n";
+    echo "    DIFF_SEPARATOR -> use /n separator\n";
+    exit(1);
+}
+
+function processFile($filePath, $showEssentials, $showDependencies)
+{
+    $block = [];
+    $packagesData = [];
+
+    foreach (file($filePath) as $line) {
+        $clean = trim($line);
+
+        if (empty($clean)) {
+            if (count($block) > 0) {
+                $packagesData[] = $block;
+                $block = [];
+            }
+        } else {
+            $parts = explode(': ', $clean);
+            if (count($parts) == 2) {
+                $block[ trim($parts[0]) ] = trim($parts[1]);    
+            }
+        }
+    }
+
+    if (count($block) > 0) {
+        $packagesData[] = $block;       
+    }
+
+    return cleanInstallData($packagesData, $showEssentials, $showDependencies);
+}
+
+function cleanInstallData($output, $showEssentials, $showDependencies)
+{
+    $packages = [];
+    $depends = [];
+
+    // generate packages and depends array
+    foreach ($output as $data) {
+        if ( 
+            !isset($data['Auto-Installed']) && 
+            isValidPackage($data['Package']) 
+        ) {
+            if (
+                !isset($data['Essential']) || 
+                (
+                    isset($data['Essential']) && $showEssentials
+                )
+            ) {
+                $packages[] = $data['Package'];
+
+                if (isset($data['Depends'])) {
+                    foreach (explode(',', $data['Depends']) as $dependency) {
+                        $dependency = trim($dependency);
+                        if (!in_array($dependency, $depends)) {
+                            $depends[] = $dependency;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    // show all installed packages
+    if ($showDependencies) {
+        sort($packages);
+        return $packages;
+    }
+
+    // show only target packages
+    $targetPackages = [];
+    foreach ($packages as $package) {
+        if (!in_array($package, $depends)) {
+            $targetPackages[] = $package;
+        }
+    }
+
+    //var_dump($depends);
+    sort($targetPackages);
+    return $targetPackages;
+}
+
+function isValidPackage($name)
+{
+    $packageBlacklist = [
+        // hak5 packages (based on mk6)
+        'pineap',
+        'aircrack-ng-hak5',
+        'cc-client',
+        'libwifi',
+        'resetssids',
+        'http_sniffer',
+        'log_daemon',
+
+        // based on hardware
+        'kmod-ath',
+        'kmod-ath9k',
+        'kmod-ath9k-htc',
+        'mt7601u-firmware',
+        'uboot-envtools',
+        'ubi-utils',
+    ];
+
+    // only kmod
+    //return !in_array($name, $packageBlacklist) && strpos($name, 'kmod-') !== false;
+
+    // not show kmod
+    //return !in_array($name, $packageBlacklist) && strpos($name, 'kmod-') === false;
+
+    // all
+    return !in_array($name, $packageBlacklist);
+}
+
+
+
+echo "\nopkg status parser - by DSR!";
+echo "\n---------------------------------------\n\n";
+$printSep   = (isset($argv[2]) && filter_var($argv[2], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)) ? "\n" : ' ';
+$statusFile = $argv[1];
+
+if (!file_exists($statusFile)) {
+    echo "[!!!] File not found: \"($statusFile)\"\n";
+    return 0;
+}
+
+
+$statusData = processFile($statusFile, false, false);
+
+echo "======== Packages (" . count($statusData) . ") ========\n";
+echo implode($printSep, $statusData);
+echo "\n\n\n";
+
+
+$statusDataEssentials = processFile($statusFile, true, false);
+$essentialPackages = [];
+foreach ($statusDataEssentials as $key) {
+    if (!in_array($key, $statusData)) {
+        $essentialPackages[] = $key;
+    }
+}
+
+echo "======== Essentials Packages (" . count($essentialPackages) . ") ========\n";
+echo implode($printSep, $essentialPackages);
+echo "\n";