Asus PCE-AC88 with hostapd: Difference between revisions

From fakedWiki
Jump to: navigation, search
No edit summary
No edit summary
Line 4: Line 4:
After initially buying a [https://www.tp-link.com/us/products/details/cat-11_Archer-T9E.html TP-Link Archer T9E], which needs a closed-source driver and doesn't even support master (AP) mode, i (finally!) did a bit more research and found the [https://www.asus.com/Networking/PCE-AC88/ Asus PCE-AC88] to be a worthy, albeit expensive, candidate.
After initially buying a [https://www.tp-link.com/us/products/details/cat-11_Archer-T9E.html TP-Link Archer T9E], which needs a closed-source driver and doesn't even support master (AP) mode, i (finally!) did a bit more research and found the [https://www.asus.com/Networking/PCE-AC88/ Asus PCE-AC88] to be a worthy, albeit expensive, candidate.


The PCE-AC88 uses the Broadcom BCM4366 chip, which is supported by the open-source <code>brcmfmac</code> driver - if you feed it the proper (still proprietary) firmware. Luckily that firmware is, acording to my previous research, readily available for Debian 9 in the <code>firmware-brcm80211</code> package - so ''what could possibly go wrong''?
The PCE-AC88 uses the Broadcom BCM4366 chip, which is supported by the open-source <code>brcmfmac</code> driver - if you feed it the proper (still proprietary) firmware. Luckily that firmware file, called <code>brcmfmac4366b-pcie.bin</code>,is readily available for Debian 9 in the <code>firmware-brcm80211</code> package - so ''what could possibly go wrong''?


Well, getting a card with a newer hardware revision (v4), which needs different firmware - that's what ''could possibly go wrong''.
Well, getting a card with a newer hardware revision (v4), which needs the firmware file <code>brcmfmac4366c-pcie.bin</code> - that's what ''could possibly go wrong''.


Fortunately i'm not the only person with issues like this, so there were other people who figured out ways how to get a firmware if there is no official source for it. So here's how i did it...
Fortunately i'm not the only person with issues like this, so there were other people who figured out ways how to get a firmware if there is no official source for it. So here's how i did it...
Line 20: Line 20:
  rm -r ./RT-AC88U ./lib
  rm -r ./RT-AC88U ./lib


This will give you the file <code>dhd.ko</code> in the current directory.
This will give you the file <code>dhd.ko</code> in the current directory. This is not the firmware, but, as mentioned before, only a kernel module containing the firmware.
The firmware
 
To figure out what the start of the firmware file looks like, we have a look at <code>brcmfmac4366b-pcie.bin</code> from  the <code>firmware-brcm80211</code> package to get the first four hex bytes:
 
$ xxd /lib/firmware/brcm/brcmfmac4366b-pcie.bin | head -n1
00000000: 00f2 3eb8 04f2 b0bf 04f2 bbbf 04f2 c6bf  ..>.............
 
Now that we know that we're looking for the bytes <code>00 F2 3E B8</code>, we can use <code>binwalk</code> to look for those bytes in the kernel module we extracted:
 
  $ binwalk -R "\x00\xf2\x3e\xb8\x04\xf2" dhd.ko
  $ binwalk -R "\x00\xf2\x3e\xb8\x04\xf2" dhd.ko
 
<nowiki>
DECIMAL      HEXADECIMAL    DESCRIPTION
DECIMAL      HEXADECIMAL    DESCRIPTION
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
256904        0x3EB88        \x00\xf2\x3e\xb8\x04\xf2
256904        0x3EB88        \x00\xf2\x3e\xb8
256936        0x3EBA8        \x00\xf2\x3e\xb8\x04\xf2
256936        0x3EBA8        \x00\xf2\x3e\xb8
</nowiki>
</nowiki>
Let's grab that offset and put it into an environment variable:
 
Let's do it once more and grab that offset to put it into an environment variable:
  $ OFFSET=$(binwalk -R "\x00\xf2\x3e\xb8\x04\xf2" dhd.ko | sed '4!d' | awk '{print $1}')
  $ OFFSET=$(binwalk -R "\x00\xf2\x3e\xb8\x04\xf2" dhd.ko | sed '4!d' | awk '{print $1}')
  $ echo ${OFFSET}
  $ echo ${OFFSET}
256904


So now we know at what offset the firmware starts, but where does it end? This gets a bit tricky, but stay with me: Kernel modules are ELF files (which you can verify by running <code>file dhd.ko</code>), so we can use <code>readelf</code> to get some information about the kernel module's structure, especially the objects (ko = kernel object) inside it:
$ readelf -s dhd.ko | grep OBJECT
...
  484: 00004220    4 OBJECT  GLOBAL DEFAULT  35 dhd_radio_up
  487: 0000442c    20 OBJECT  GLOBAL DEFAULT  35 dlimagedate_4366c0
  521: 00000654    4 OBJECT  GLOBAL DEFAULT  35 dhd_download_fw_on_driver
  526: 00004448 0x10b351 OBJECT  GLOBAL DEFAULT  35 dlarray_4366c0
  527: 00004210    4 OBJECT  GLOBAL DEFAULT  35 dhd_console_ms
  544: 00001058    4 OBJECT  GLOBAL DEFAULT  45 dhd_found
  545: 00004218    4 OBJECT  GLOBAL DEFAULT  35 dhd_master_mode
...


$ readelf -s dhd.ko | grep dlarray_4366c0
We see a long list of tiny objects (the third column is the size), but one that sticks out because of its size, and the name <code>dlarray_4366c0</code> also implies that we have found the object we are looking for - and its size.
  526: 00004448 0x10b351 OBJECT  GLOBAL DEFAULT  35 dlarray_4366c0


$ SIZE=$(readelf -s dhd.ko | grep dlarray_4366c0 | awk '{print $3}' | xargs printf "%d\n")
So let's do that again, and also grab the size and put it into an environment variable:
$ echo ${SIZE}
$ SIZE=$(readelf -s dhd.ko | grep dlarray_4366c0 | awk '{print $3}' | xargs printf "%d\n")
$ echo ${SIZE}
1094481


$ dd if=dhd.ko skip=${OFFSET} ibs=1 count=${SIZE} of=brcmfmac4366c-pcie.bin
$ dd if=dhd.ko skip=${OFFSET} ibs=1 count=${SIZE} of=brcmfmac4366c-pcie.bin

Revision as of 13:54, 8 December 2018

Intro

For several years i've been using hostapd on my home server to create a Wifi access point for all my devices, but due to a recent replacement of the server's hardware, i needed to get a new Wifi adapter as the new mainboard didn't have an PCI slot anymore.

After initially buying a TP-Link Archer T9E, which needs a closed-source driver and doesn't even support master (AP) mode, i (finally!) did a bit more research and found the Asus PCE-AC88 to be a worthy, albeit expensive, candidate.

The PCE-AC88 uses the Broadcom BCM4366 chip, which is supported by the open-source brcmfmac driver - if you feed it the proper (still proprietary) firmware. Luckily that firmware file, called brcmfmac4366b-pcie.bin,is readily available for Debian 9 in the firmware-brcm80211 package - so what could possibly go wrong?

Well, getting a card with a newer hardware revision (v4), which needs the firmware file brcmfmac4366c-pcie.bin - that's what could possibly go wrong.

Fortunately i'm not the only person with issues like this, so there were other people who figured out ways how to get a firmware if there is no official source for it. So here's how i did it...

Howto

The first step is to download the current firmware package for the Asus RT-AC88U - which is the Asus Wifi router with the same chip in it. Why? It also runs Linux, so it obviously also needs the firmware for that chip! You can pick any OS (e.g. "Others") from the dropdown menu, as long as you download the file below "Firmware". For me that was version 3.0.0.4.384.45149, released just 2 days ago.

Download that file to a folder, make sure you have p7zip installed, then run the following to extract the kernel module that contains the firmware somewhere inside it:

7z x FW_RT_AC88U_300438445149.zip
7z x RT-AC88U/RT-AC88U_3.0.0.4_384_45149-g467037b.trx lib/modules/2.6.36.4brcmarm/kernel/drivers/net/dhd/dhd.ko
mv lib/modules/2.6.36.4brcmarm/kernel/drivers/net/dhd/dhd.ko ./
rm -r ./RT-AC88U ./lib

This will give you the file dhd.ko in the current directory. This is not the firmware, but, as mentioned before, only a kernel module containing the firmware.

To figure out what the start of the firmware file looks like, we have a look at brcmfmac4366b-pcie.bin from the firmware-brcm80211 package to get the first four hex bytes:

$ xxd /lib/firmware/brcm/brcmfmac4366b-pcie.bin | head -n1
00000000: 00f2 3eb8 04f2 b0bf 04f2 bbbf 04f2 c6bf  ..>.............

Now that we know that we're looking for the bytes 00 F2 3E B8, we can use binwalk to look for those bytes in the kernel module we extracted:

$ binwalk -R "\x00\xf2\x3e\xb8\x04\xf2" dhd.ko

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
256904        0x3EB88         \x00\xf2\x3e\xb8
256936        0x3EBA8         \x00\xf2\x3e\xb8

Let's do it once more and grab that offset to put it into an environment variable:

$ OFFSET=$(binwalk -R "\x00\xf2\x3e\xb8\x04\xf2" dhd.ko | sed '4!d' | awk '{print $1}')
$ echo ${OFFSET}
256904

So now we know at what offset the firmware starts, but where does it end? This gets a bit tricky, but stay with me: Kernel modules are ELF files (which you can verify by running file dhd.ko), so we can use readelf to get some information about the kernel module's structure, especially the objects (ko = kernel object) inside it:

$ readelf -s dhd.ko | grep OBJECT
...
  484: 00004220     4 OBJECT  GLOBAL DEFAULT   35 dhd_radio_up
  487: 0000442c    20 OBJECT  GLOBAL DEFAULT   35 dlimagedate_4366c0
  521: 00000654     4 OBJECT  GLOBAL DEFAULT   35 dhd_download_fw_on_driver
  526: 00004448 0x10b351 OBJECT  GLOBAL DEFAULT   35 dlarray_4366c0
  527: 00004210     4 OBJECT  GLOBAL DEFAULT   35 dhd_console_ms
  544: 00001058     4 OBJECT  GLOBAL DEFAULT   45 dhd_found
  545: 00004218     4 OBJECT  GLOBAL DEFAULT   35 dhd_master_mode
...

We see a long list of tiny objects (the third column is the size), but one that sticks out because of its size, and the name dlarray_4366c0 also implies that we have found the object we are looking for - and its size.

So let's do that again, and also grab the size and put it into an environment variable:

$ SIZE=$(readelf -s dhd.ko | grep dlarray_4366c0 | awk '{print $3}' | xargs printf "%d\n")
$ echo ${SIZE}
1094481

$ dd if=dhd.ko skip=${OFFSET} ibs=1 count=${SIZE} of=brcmfmac4366c-pcie.bin $ cp brcmfmac4366c-pcie.bin /lib/firmware/brcm/brcmfmac4366c-pcie.bin $ cp brcmfmac4366c-pcie.bin /lib/firmware/brcm/brcmfmac4366c-pcie.txt

[ 4254.199723] usbcore: registered new interface driver brcmfmac [ 4254.306332] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac4366c-pcie for chip BCM4366/4 [ 4254.307882] brcmfmac 0000:42:00.0: firmware: direct-loading firmware brcm/brcmfmac4366c-pcie.bin [ 4254.308213] brcmfmac 0000:42:00.0: firmware: direct-loading firmware brcm/brcmfmac4366c-pcie.txt [ 4255.083576] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac4366c-pcie for chip BCM4366/4 [ 4255.083600] brcmfmac 0000:42:00.0: firmware: failed to load brcm/brcmfmac4366c-pcie.clm_blob (-2) [ 4255.083616] brcmfmac 0000:42:00.0: Direct firmware load for brcm/brcmfmac4366c-pcie.clm_blob failed with error -2 [ 4255.083618] brcmfmac: brcmf_c_process_clm_blob: no clm_blob available (err=-2), device may have limited channels available [ 4255.083843] brcmfmac: brcmf_c_preinit_dcmds: Firmware: BCM4366/4 wl0: Aug 14 2018 10:35:53 version 10.10.122.303 (r666429) FWID 01-ef91d5ac [ 4255.096622] brcmfmac 0000:42:00.0 wlp66s0: renamed from wlan0

$ iw phy#1 info Wiphy phy1

       max # scan SSIDs: 10
       max scan IEs length: 2048 bytes
       max # sched scan SSIDs: 0
       max # match sets: 0
       max # scan plans: 1
       max scan plan interval: -1
       max scan plan iterations: 0
       Retry short limit: 7
       Retry long limit: 4
       Coverage class: 0 (up to 0m)
       Device supports roaming.
       Supported Ciphers:
               * WEP40 (00-0f-ac:1)
               * WEP104 (00-0f-ac:5)
               * TKIP (00-0f-ac:2)
               * CCMP-128 (00-0f-ac:4)
               * CMAC (00-0f-ac:6)
       Available Antennas: TX 0 RX 0
       Supported interface modes:
                * IBSS
                * managed
                * AP
                * P2P-client
                * P2P-GO
                * P2P-device
       Band 1:
               Capabilities: 0x1022
                       HT20/HT40
                       Static SM Power Save
                       RX HT20 SGI
                       No RX STBC
                       Max AMSDU length: 3839 bytes
                       DSSS/CCK HT40
               Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
               Minimum RX AMPDU time spacing: 16 usec (0x07)
               HT TX/RX MCS rate indexes supported: 0-31
               Bitrates (non-HT):
                       * 1.0 Mbps
                       * 2.0 Mbps (short preamble supported)
                       * 5.5 Mbps (short preamble supported)
                       * 11.0 Mbps (short preamble supported)
                       * 6.0 Mbps
                       * 9.0 Mbps
                       * 12.0 Mbps
                       * 18.0 Mbps
                       * 24.0 Mbps
                       * 36.0 Mbps
                       * 48.0 Mbps
                       * 54.0 Mbps
               Frequencies:
                       * 2412 MHz [1] (20.0 dBm)
                       * 2417 MHz [2] (20.0 dBm)
                       * 2422 MHz [3] (20.0 dBm)
                       * 2427 MHz [4] (20.0 dBm)
                       * 2432 MHz [5] (20.0 dBm)
                       * 2437 MHz [6] (20.0 dBm)
                       * 2442 MHz [7] (20.0 dBm)
                       * 2447 MHz [8] (20.0 dBm)
                       * 2452 MHz [9] (20.0 dBm)
                       * 2457 MHz [10] (20.0 dBm)
                       * 2462 MHz [11] (20.0 dBm)
                       * 2467 MHz [12] (20.0 dBm)
                       * 2472 MHz [13] (20.0 dBm)
                       * 2484 MHz [14] (disabled)
       Band 2:
               Capabilities: 0x1062
                       HT20/HT40
                       Static SM Power Save
                       RX HT20 SGI
                       RX HT40 SGI
                       No RX STBC
                       Max AMSDU length: 3839 bytes
                       DSSS/CCK HT40
               Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
               Minimum RX AMPDU time spacing: 16 usec (0x07)
               HT TX/RX MCS rate indexes supported: 0-31
               VHT Capabilities (0x0c1b4064):
                       Max MPDU length: 3895
                       Supported Channel Width: 160 MHz
                       short GI (80 MHz)
                       short GI (160/80+80 MHz)
                       MU Beamformer
                       MU Beamformee
               VHT RX MCS set:
                       1 streams: MCS 0-9
                       2 streams: MCS 0-9
                       3 streams: MCS 0-9
                       4 streams: MCS 0-9
                       5 streams: not supported
                       6 streams: not supported
                       7 streams: not supported
                       8 streams: not supported
               VHT RX highest supported: 0 Mbps
               VHT TX MCS set:
                       1 streams: MCS 0-9
                       2 streams: MCS 0-9
                       3 streams: MCS 0-9
                       4 streams: MCS 0-9
                       5 streams: not supported
                       6 streams: not supported
                       7 streams: not supported
                       8 streams: not supported
               VHT TX highest supported: 0 Mbps
               Bitrates (non-HT):
                       * 6.0 Mbps
                       * 9.0 Mbps
                       * 12.0 Mbps
                       * 18.0 Mbps
                       * 24.0 Mbps
                       * 36.0 Mbps
                       * 48.0 Mbps
                       * 54.0 Mbps
               Frequencies:
                       * 5170 MHz [34] (disabled)
                       * 5180 MHz [36] (20.0 dBm)
                       * 5190 MHz [38] (disabled)
                       * 5200 MHz [40] (20.0 dBm)
                       * 5210 MHz [42] (disabled)
                       * 5220 MHz [44] (20.0 dBm)
                       * 5230 MHz [46] (disabled)
                       * 5240 MHz [48] (20.0 dBm)
                       * 5260 MHz [52] (disabled)
                       * 5280 MHz [56] (disabled)
                       * 5300 MHz [60] (disabled)
                       * 5320 MHz [64] (disabled)
                       * 5500 MHz [100] (disabled)
                       * 5520 MHz [104] (disabled)
                       * 5540 MHz [108] (disabled)
                       * 5560 MHz [112] (disabled)
                       * 5580 MHz [116] (disabled)
                       * 5600 MHz [120] (disabled)
                       * 5620 MHz [124] (disabled)
                       * 5640 MHz [128] (disabled)
                       * 5660 MHz [132] (disabled)
                       * 5680 MHz [136] (disabled)
                       * 5700 MHz [140] (disabled)
                       * 5720 MHz [144] (disabled)
                       * 5745 MHz [149] (disabled)
                       * 5765 MHz [153] (disabled)
                       * 5785 MHz [157] (disabled)
                       * 5805 MHz [161] (disabled)
                       * 5825 MHz [165] (disabled)
       Supported commands:
                * new_interface
                * set_interface
                * new_key
                * start_ap
                * join_ibss
                * set_pmksa
                * del_pmksa
                * flush_pmksa
                * remain_on_channel
                * frame
                * set_wiphy_netns
                * set_channel
                * start_p2p_device
                * connect
                * disconnect
                * crit_protocol_start
                * crit_protocol_stop
                * Unknown command (122)
       Supported TX frame types:
                * managed: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
                * P2P-client: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
                * P2P-GO: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
                * P2P-device: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
       Supported RX frame types:
                * managed: 0x40 0xd0
                * P2P-client: 0x40 0xd0
                * P2P-GO: 0x00 0x20 0x40 0xa0 0xb0 0xc0 0xd0
                * P2P-device: 0x40 0xd0
       WoWLAN support:
                * wake up on disconnect
                * wake up on magic packet
                * wake up on pattern match, up to 8 patterns of 1-128 bytes,
                  maximum packet offset 1500 bytes
       software interface modes (can always be added):
       valid interface combinations:
                * #{ managed } <= 1, #{ P2P-device } <= 1, #{ P2P-client, P2P-GO } <= 1,
                  total <= 3, #channels <= 1
                * #{ managed } <= 1, #{ AP } <= 1, #{ P2P-client } <= 1, #{ P2P-device } <= 1,
                  total <= 4, #channels <= 1
                * #{ AP } <= 4,
                  total <= 4, #channels <= 1, STA/AP BI must match
       Device supports scan flush.