MT7688 AP-Client模式

最近我在研究MT7688的闭源WIFI源码,发现默认开启了AP和AP-Client模式,但STA模式默认没选中,估计要支持的话得修改代码。

MT7688我以及在用LEDE了,新的系统很流畅,所有顺便也把WIFI移植了,修改了几个不兼容的地方基本OK了。本来是想公开的,但这个是MTK闭源驱动-_-!!!,不能公开。

涉及到的MT7688.dat里的驱动参数是这么几个:

ApCliEnable
ApCliSsid
ApCliBssid // 这个不是必须,如果不提供,wifi驱动会自己去查找
ApCliAuthMode
ApCliEncrypType
ApCliWPAPSK

但是OpenWRT里默认的uci2dat支持这些参数有BUG,因为uci2dat默认只支持一个wifi-iface,但AP-Client模式必须有两个wifi-iface,一个做AP,一个做Client。修改uci2data:

@@ -1061,23 +1064,69 @@ void hooker(FILE * fp, param * p, const char * devname)
 #endif
    else if (0 == strmatch(p->dat_key, "ApCliEnable"))
    {
-       FPRINT(fp, p, "%s", wifi_cfg[N].vifs[i].apcli_enable.value);
+        int j;
+       for(j=0; j<wifi_cfg[N].vifnum; j++)
+       {
+           if (strlen(wifi_cfg[N].vifs[j].apcli_enable.value) > 0)
+               FPRINT(fp, p, "%s", wifi_cfg[N].vifs[j].apcli_enable.value);
+       }
+       if (j < wifi_cfg[N].vifnum)
+           FPRINT(fp, p, "%s", wifi_cfg[N].vifs[i].apcli_enable.value);
    }
    else if (0 == strmatch(p->dat_key, "ApCliSsid"))
    {
-       FPRINT(fp, p, "%s", wifi_cfg[N].vifs[i].apcli_ssid.value);
+        int j;
+       for(j=0; j<wifi_cfg[N].vifnum; j++)
+       {
+           if (strlen(wifi_cfg[N].vifs[j].apcli_ssid.value) > 0)
+               FPRINT(fp, p, "%s", wifi_cfg[N].vifs[j].apcli_ssid.value);
+       }
+       if (j < wifi_cfg[N].vifnum)
+           FPRINT(fp, p, "%s", wifi_cfg[N].vifs[i].apcli_ssid.value);
+   }
+   else if (0 == strmatch(p->dat_key, "ApCliBssid"))
+   {
+        int j;
+       for(j=0; j<wifi_cfg[N].vifnum; j++)
+       {
+           if (strlen(wifi_cfg[N].vifs[j].apcli_bssid.value) > 0)
+               FPRINT(fp, p, "%s", wifi_cfg[N].vifs[j].apcli_bssid.value);
+       }
+       if (j < wifi_cfg[N].vifnum)
+           FPRINT(fp, p, "%s", wifi_cfg[N].vifs[i].apcli_bssid.value);
    }
    else if (0 == strmatch(p->dat_key, "ApCliAuthMode"))
    {
-       FPRINT(fp, p, "%s", wifi_cfg[N].vifs[i].apcli_authmode.value);
+        int j;
+       for(j=0; j<wifi_cfg[N].vifnum; j++)
+       {
+           if (strlen(wifi_cfg[N].vifs[j].apcli_authmode.value) > 0)
+               FPRINT(fp, p, "%s", wifi_cfg[N].vifs[j].apcli_authmode.value);
+       }
+       if (j < wifi_cfg[N].vifnum)
+           FPRINT(fp, p, "%s", wifi_cfg[N].vifs[i].apcli_authmode.value);
    }
    else if (0 == strmatch(p->dat_key, "ApCliEncrypType"))
    {
-       FPRINT(fp, p, "%s", wifi_cfg[N].vifs[i].apcli_encryptype.value);
+        int j;
+       for(j=0; j<wifi_cfg[N].vifnum; j++)
+       {
+           if (strlen(wifi_cfg[N].vifs[j].apcli_encryptype.value) > 0)
+               FPRINT(fp, p, "%s", wifi_cfg[N].vifs[j].apcli_encryptype.value);
+       }
+       if (j < wifi_cfg[N].vifnum)
+           FPRINT(fp, p, "%s", wifi_cfg[N].vifs[i].apcli_encryptype.value);
    }
    else if (0 == strmatch(p->dat_key, "ApCliWPAPSK"))
    {
-       FPRINT(fp, p, "%s", wifi_cfg[N].vifs[i].apcli_password.value);
+        int j;
+       for(j=0; j<wifi_cfg[N].vifnum; j++)
+       {
+           if (strlen(wifi_cfg[N].vifs[j].apcli_password.value) > 0)
+               FPRINT(fp, p, "%s", wifi_cfg[N].vifs[j].apcli_password.value);
+       }
+       if (j < wifi_cfg[N].vifnum)
+           FPRINT(fp, p, "%s", wifi_cfg[N].vifs[i].apcli_password.value);
    }
     /* the rest part is quite simple! */
     else

编辑/etc/config/wireless:

config wifi-device 'mt7628'
    option type 'mt7628'
    option vendor 'ralink'
    option band '2.4G'
    option channel '11'   // 这个必须是你要连接路由器的信道一致,否则会连不上的
    option country 'CN'
    option region '1'

config wifi-iface 'ap'
    option device 'mt7628'
    option ifname 'ra0'
    option network 'lan'
    option mode 'ap'
    option ssid 'AP名'
    option key 'AP密码'
    option encryption 'psk2'
    option wpa_crypto 'TKIP+AES'
    option hidden '1'

config wifi-iface 'sta'
    option device 'mt7628'
    option ifname 'apcli0'
    option network 'wan' // 作为外网接口
    option mode 'sta'   //  这个没用,uci2dat根本不解析
    option ApCliEnable '1'
    option ApCliSsid '路由器名'
    option ApCliAuthMode 'WPA2PSK'
    option encryption 'psk2'     // 这个必须,如果省略这个会导致WIFI驱动错误的认证协议
    option ApCliEncrypType 'TKIP'
    option ApCliWPAPSK '路由器密码'

在/etc/config/network里修改wan:

config interface 'wan'
    option ifname 'apcli0'
    option force_link '1'
    option proto  dhcp

一开始调试死活连不上,逼得只能看WIFI驱动代码发现底层的认证协议需要加上option encryption,还有就是如果是AP-Client模式的话就不能自动选择信道了,必须跟着路由器的信道来,其实把AP和Client做个桥接就是一个信号中继了,不过WIFI驱动底层好像支持MAC层上的中继,这个没空研究了。

在LEDE的iwinfo没法查看WIFI的Link Quality,而且iw也输出为空,原因就是WIFI驱动还没启用CFG80211支持。但是MT7688的WIFI驱动比较老,导致CFG80211的代码跟最新的内核不兼容,所以我疯狂的在github上一遍查找补丁,一遍修改代码。最后总算是能运行iw了,但是iwinfo输出的信息不全,估计是通过ioctl的方式与驱动打交道,驱动不支持,这个后面再修复。

我关于最近爆出的WIFI的WPA2漏洞KRACK,深感震惊!基本上所有WIFI设备没有幸免,那些IoT设备估计永远都没法更新补丁。根据漏洞描述,基本上是可以揭秘客户端或双向通信的数据,但不能破解WIFI密码!

BTW: 这个是几个礼拜前搞的了,放草稿箱里都要长草了,今天晚上抽空填了坑,近年来记忆力衰退,必须多记录!!!

MT7688 AP-Client模式》上有2条评论

  1. 你好,可以发我一份mtk 7620驱动移植的源码吗,我想给自己编译一下K2给自己用,但是wifi驱动一直不好,也找不到相应的教程,希望你能帮我一下。谢谢!

  2. 你好 WIFI驱动代码发现底层的认证协议需要加上option encryption

    能告诉我wifi driver关于这个具体代码在哪里吗

发表评论

电子邮件地址不会被公开。 必填项已用*标注