筆者分析了360 P1路由器上的朋友專享網絡功能,發現其主要由如下子功能組成:
1. APP點擊“立即開啟”,則路由器會多出一個新的SSID:360朋友專享網絡-8463。此SSID不加密;同時,原有的主SSID不變
2. STA接入此新SSID后
u 可以獲得IP地址,且獲得的IP地址與接入主SSID設備獲取的IP地址在同一個網段;
u 可以訪問外網;
u 不可以訪問360路由器的Web,
u 無法ping通360路由器的ip地址
u 無法ping通其他連入此路由器的其他客戶端(包括連入360路由器的任何一個SSID)
u 在路由器的下掛終端列表中,可以看到此STA。且標記為“訪客”
3. 此朋友網絡在開啟后,會有120秒的倒數計時。到時候,此網絡會變成隱藏
筆者手里也有一個基於MTK7620N的路由器,且基於OpenWRT的原生SDK(R43400),故筆者考慮將上述功能移植到此路由器中(APP部分除外)。
主要涉及如下工作:
1. 要支持第二個SSID;且此SSID的MAC是自動生成:基於主SSID,MAC地址自增1
實現方案:
支持第二個SSID,需要修改/etc/config/wireless,增加一個wifi-iface的section 配置項
2. 第二個SSID需要實現:與其他橋接口的隔離:需要在brctl+橋協議棧上,上做定制開發
實現方案:
l 修改brctl_cmd.c(bridge-utils-1.5/brctl),在數組commands中,增加一個新命令:
{ 3, "setisolation", br_cmd_setisolation,
"<bridge> <port> <1/0>\tset port isolation" },
l 修改brctl_cmd.c(bridge-utils-1.5/brctl),加入新函數br_cmd_setisolation的實現定義:調用函數br_set_isolation_enable
l 修改libbridge_devif.c(bridge-utils-1.5/libbridge),增加新函數br_set_isolation_enable的實現:直接利用port_set接口,對/sys/devices/virtual/net/xxx/brport/isolate_mode的值進行修改。
注意:isolate_mode參數在內核中已經存在,對應內核橋端口屬性中已經有的屬性:BR_ISOLATE_MODE,1表示隔離;0表示不隔離;此屬性,用於控制該橋端口是否轉發報文對本地收發報文不影響
3. 從第二個SSID接入的終端所發出的報文,僅僅可以路由轉發,不可以訪問本地(當然,DHCP報文允許到本地)
實現方案:
u 利用iptables的phyxdev的match模塊,在INPUT鏈上建立如下規則:僅僅允許DHCP報文以及DNS報文可以到本地
Iptables –I INPUT –m physdev –physdev-in wlan2 –p udp –sport 68 --dport 67 –j ACCEPT
Iptables –I INPUT –m physdev –physdev-in wlan2 –p udp --dport 53 –j ACCEPT
Iptables –I INPUT –m physdev –physdev-in wlan2 –j DROP
u 需要做如下編譯配置:
用戶態:network->firewall->iptables->iptables-mod-extra
內核態:Networking support->networking options->netfilter->Advanced netfilter configuration
Networking support->networking options->netfilter->Bridged IP/ARP packets filtering
Networking support->networking options->netfilter->core netfilter configuration -> netfilter xtables support
Networking support->networking options->netfilter->core netfilter configuration -> “physdev” match support <M> --- 必須是模塊編譯 u /proc/sys/net/bridge/bridge-nf-call-iptables 需要為 1
4. 第二個SSID需要實現:與接入同一個SSID的其他STA隔離:需要在iw+驅動上做定制開發
實現方案:
u 擴充genl_netlink參數實現新命令: dev <devname> set inner_deliver <on|off>
control the STAs which belong to the same ssid can transfer data to each other or not。
u 修改compat-wireless-2014-11-04/net/mac80211/ieee80211_i.h文件,在結構體ieee80211_sub_if_data中增加成員:inner_deliver
u 修改ieee80211_deliver_skb (compat-wireless-2014-11-04\net\mac80211\rx.c),增加同一個SSID下的STA之間是否轉發的判斷處理:
if(sdata->inner_deliver != 1) {
printk("in ieee80211_deliver_skb, not deliver skd \n");
dev_kfree_skb(skb);
skb = NULL;
}
5. 第二個 SSID 上發出的 beacon 幀,需要定時處理為:隱藏 SSID 參數實現方案:
u 修改/etc/config/wireless,對第二個SSID,增加如下配置:
config wifi-iface
option device 'radio0'
option network 'lan'
option mode 'ap'
option encryption 'none'
option maxassoc '32'
option ssid 'LeU_0acc_2'
option hidden '1' --- 決定ssid是否廣播,即是否隱藏
u 使用腳本命令: wifi up radio0,使得hostapd重啟
6. 設備管理模塊需要將從第二個SSID接入的終端,一並管理起來,並做顯著區別的顯示:訪客