Asus PCE-AC88 with hostapd

From fakedWiki
Revision as of 11:12, 9 December 2018 by Jan (talk | contribs)
Jump to: navigation, search

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...


Firmware

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.


Preparation

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.


Investigation

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 the position of those bytes in the kernel module:

$ 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


Extraction

We have the kernel module, we know where the firmware starts, and we know the size of it, so now we can use dd to extract the section that we think is is the firmware from the kernel module:

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

This is not necessary, but let's get the full details about the firmware we just extracted:

$ strings brcmfmac4366c-pcie.bin_10.10.122.47 | grep Version
4366c0-roml/pcie-ag-splitrx-fdap-mbss-mfp-wnm-osen-wl11k-wl11u-txbf-pktctx-amsdutx-ampduretry-chkd2hdma-proptxstatus-11nprop-obss-dbwsw-ringer-dmaindex16-bgdfs-stamon-hostpmac-murx-splitassoc-hostmemucode-dyn160-txpwr-stamon Version: 10.10.122.47 CRC: 13f8b3a1 Date: Tue 2018-08-14 10:45:51 CST FWID 01-ef91d5ac

Or in a more readable format:

Features pcie-ag-splitrx-fdap-mbss-mfp-wnm-osen-wl11k-wl11u-txbf-pktctx-amsdutx-ampduretry-chkd2hdma-proptxstatus-11nprop-obss-dbwsw-ringer-dmaindex16-bgdfs-stamon-hostpmac-murx-splitassoc-hostmemucode-dyn160-txpwr-stamon
Version 10.10.122.47
CRC 13f8b3a1
Date Tue 2018-08-14 10:45:51 CST
FWID 01-ef91d5ac


Installation

The brcmfmac module is looking for its firmware files in a specific folder, so you need to copy the extracted firmware there:

 $ cp brcmfmac4366c-pcie.bin /lib/firmware/brcm/brcmfmac4366c-pcie.bin


Initialization

You probably have the brcmfmac module still loaded, so let's unload and reload it:

$ modprobe -r brcmfmac
$ modprobe brcmfmac

If everything went well, dmesg should show you that it was able to initialize the chip with the firmware, even though it complains about brcm/brcmfmac4366c-pcie.txt and brcm/brcmfmac4366c-pcie.clm_blob:

[62448.893550] usbcore: registered new interface driver brcmfmac
[62449.000758] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac4366c-pcie for chip BCM4366/4
[62449.002127] brcmfmac 0000:42:00.0: firmware: direct-loading firmware brcm/brcmfmac4366c-pcie.bin
[62449.002137] brcmfmac 0000:42:00.0: firmware: failed to load brcm/brcmfmac4366c-pcie.txt (-2)
[62449.002330] brcmfmac 0000:42:00.0: Direct firmware load for brcm/brcmfmac4366c-pcie.txt failed with error -2
[62449.753733] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac4366c-pcie for chip BCM4366/4
[62449.753749] brcmfmac 0000:42:00.0: firmware: failed to load brcm/brcmfmac4366c-pcie.clm_blob (-2)
[62449.753926] brcmfmac 0000:42:00.0: Direct firmware load for brcm/brcmfmac4366c-pcie.clm_blob failed with error -2
[62449.753928] brcmfmac: brcmf_c_process_clm_blob: no clm_blob available (err=-2), device may have limited channels available
[62449.754055] brcmfmac: brcmf_c_preinit_dcmds: Firmware: BCM4366/4 wl0: Sep 12 2016 13:26:44 version 10.10.69.6908 (r658761) FWID 01-fed440e1
[62449.767104] brcmfmac 0000:42:00.0 wlp66s0: renamed from wlan0


Verification

Run the command below, and if you get a similar output you now have a working PCE-AC88.

$ iw phy#0 info
Wiphy phy0
        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.

hostapd

Not yet...