openWRT学习心得

OPENWRT学习总结

目录

Openwrt编译及烧写... 4

Build.tex. 4

Building an image. 4

Download OpenWrt 4

The directory structure. 4

tools和toolchain. 4

Package. 5

Target 5

Building OpenWrt 5

Creating packages 5

Creating binary packages 5

Creating kernel modules packages 6

Conventions 6

Troubleshooting. 6

Using build environments 6

Config.tex. 6

配置文件结构... 6

Parsing configuration files in custom scripts 6

wireless.tex文档部分学习... 7

通用的atheros无线配置:... 7

通用的多radio atheros无线配置:... 8

配置文件详述... 8

Mesh Point 9

WDS. 10

Unencrypted WDS connections 10

Encrypted WDS connections 10

802.1x configurations 11

EAP-PEAP. 11

限制说明... 11

Adding a new driver configuration. 11

Network-scripts.tex. 12

Using the network scripts 12

Writing protocol handers 12

Network.tex. 12

网络接口配置... 12

Static. 13

DHCP. 13

PPPOE. 13

MTU设置... 14

设置静态路由... 14

设置交换机... 14

IPV6设置... 14

Init_script.tex. 15

功能脚本... 15

etc/rc.common说明... 15

重载初始化脚本函数... 17

定制脚本命令... 18

Iw.. 18

Iw命令行... 18

iw说明... 20

列出所有命令行... 21

列出所有命令及帮助... 21

列出设备支持能力,如带宽信息、802.11n信息... 21

扫描... 21

监听事件,调试目的... 21

获取链路状态(STA适用)... 21

建立连接... 21

获取STA统计信息... 22

获取特定STA的统计... 22

修改transmit bitrates 22

设置txpower 22

省电模式... 22

添加接口... 22

删除接口... 23

设置频率... 23

设置信道... 23

设置RTS. 23

设置FRAG.. 23

修改monitor接口标识... 24

更新regulatory domain (国家码???)... 24

创建mesh 接口... 24

设置WDS peer 24

AP和client模式使用4-address 24

wifi启动... 25

WEB设置... 27

LuCI(Lua Configuration Interface)... 27

Web设置... 27

web小测试... 28

频率信道转换函数... 28

Openwrt编译及烧写

Build.tex

     Building an image

       Openwrt采用不同的方式来build a firmware,从头开始来dowloading、patching、compiling一切,包括交叉编译器。也就是说,openwrt不包含任何可执行程序,甚至源代码,他自动下载源代码、打补丁来满足指定平台,并编译。通过修改template,我们就可以改变此过程中的任何步骤。

       例如,如果一新的kernel发布了,只需要简单地修订其中的一个makefile文件就会download最新的kernel,patch,编译新的firmware映像。这不仅适用于kernel,也适用于openwrt的所有模块,包含openwrt。这使得openwrt保持最新的编译器、最新的内核及最新的应用。

     Download OpenWrt

       Openwrt的下载方式:

       svn checkout svn://svn.openwrt.org/openwrt/trunk openwrt-trunk

       在https://dev.openwrt.org/上有一个trac接口,可用来检视svn提交及浏览源代码仓库。

     The directory structure

       有四个关键目录:Tools、Toolchain、Package、Target。

      tools和toolchain

       其中tools和toolchain是通用工具,用来编译firmware image、编译器及C库。其编译结果是三个新的目录:build_dir/host,临时目录,用来build target独立的工具;build_dir/toolchain-<arch>,用来编译特定architecture的toolchain;staging_dir/toolchain-<arch>,toolchain编译结果的安装目录;对于toolchain目录不需要做任何事情,除非you intend to add a new version of one of the components above。

      Package

       Package包目录,在openwrt firmware中,所有模块均是.ipk,这种软件包可用来add to iremware中来提供新的特性或去除以节省空间。这些软件包也是在主干外维护的,并可通过package feed系统来获取到。

       ./scripts/feeds update

      

Those packages can be used to extend the functionality of the build system and need to be symlinked into the main trunk. Once you do that, the packages will show up in the menu for configuration. You would do something like this:

./scripts/feeds search nmap

Search results in feed 'packages':

nmap       Network exploration and/or security auditing utility

$ ./scripts/feeds install nmap

To include all packages, issue the following command:

$ make package/symlinks

Target

Target指的是嵌入式平台,包括特定嵌入式平台的内容。其中target/linux目录,which is broken down by platform <arch>,包含了特定平台的kernel patch 、profile config。Target/image目录描述了怎么为特定平台打包firmware。

Target和package步骤均会使用build_dir/<arch>作为临时目录来编译,另外,toolchain、target、package步骤所下载的内容均会放到dl目录下。

Building OpenWrt

       略

Creating packages

       略

Creating binary packages

       略

Creating kernel modules packages

       略

Conventions

       略

Troubleshooting

       略

Using build environments

       略

Config.tex

配置文件结构

Structure of the configuration files

配置文件分为sections和options/values对。每一section有一type,但不一定需要name。每一option有一个name和value,写在其所属于的section中。

语法如下:

config      <type> ["<name>"]      # Section

    option  <name> "<value>"       # Option

每一参数应当是单一字符串,is formatted exactly like a parameter for a shell function。引号及特殊字符规则仍然适用,他们将被shell解释。

Parsing configuration files in custom scripts

       为了load configuration files,必须包含通用功能脚本:

       . /etc/functions.sh

       这样就可以使用config_load<name>来加载配置文件,功能会首先以<name>作为文件名来检查,并从/etc/config中加载。(这是最通用的使用方式)

       If you want to use special callbacks for sections and/or options, you need to define the following shell functions before running \texttt{config\_load} (after including \texttt{/etc/functions.sh}):

config_cb() {

    local type="$1"

    local name="$2"

    # commands to be run for every section

}

option_cb() {

    # commands to be run for every option

}

wireless.tex文档部分学习

       WiFi配置文件为/etc/config/wireless。当前支持broadcom、atheros、mac80211。

       设备首次启动会检测无线卡类型,并创建一个默认配置文件(sample configuration file)。每一无线驱动都有自己的配置脚本(/lib/wifi/driver_name.sh),用来处理驱动特定的选项及配置,脚本也会调用驱动特定的二进制如适用于broadcom的wlc,适用于atheros、mac80211的hostapd和wpa_supplicant。

       这种结构(architecture)抽象了驱动配置。

       通用的broadcom无线配置(略):

       通用的mac80211无线配置(略):

通用的atheros无线配置:

config wifi-device      "wifi0"

    option type         "atheros"

    option channel      "5"

    option hwmode      "11g"

config wifi-iface

    option device       "wifi0"

#   option network  lan

    option mode         "ap"

    option ssid         "OpenWrt"

    option hidden       "0"

option encryption   "none"

通用的多radio atheros无线配置:

config wifi-device  wifi0

    option type     atheros

    option channel  1

config wifi-iface

    option device   wifi0

#   option network  lan

    option mode     ap

    option ssid     OpenWrt_private

    option hidden   0

    option encryption none

config wifi-device  wifi1

    option type     atheros

    option channel  11

config wifi-iface

    option device   wifi1

#   option network  lan

    option mode     ap

    option ssid     OpenWrt_public

    option hidden   1

    option encryption none

配置文件详述

配置文件有两部分,一是wifi-device,指的是物理wifi接口,而wifi-iface指的是其上的虚拟接口,即VAP。

整个的配置文件如下:

config wifi-device    wifi device name

    option type       broadcom, atheros, mac80211      所支持的驱动类型

    option country    us, uk, fr, de, etc.          国家码

    option channel    1-14               wifi信道,依赖于国家码

    option maxassoc   1-128 (broadcom only) 关联的最大client数目,仅broadcom支持。

    option distance   1-n (meters)  AP与最远的client的距离,仅atheros芯片支持

    option hwmode     11b, 11g, 11a, 11bg (atheros, mac80211) 频率带宽,仅atheros支持。

    option rxantenna  0,1,2 (atheros, broadcom) 接收端天线标识 (Antenna identifier)

    option txantenna  0,1,2 (atheros, broadcom) 发送端天线标识 (Antenna identifier)

    option txpower  transmission power in dBm 发射功率transmission power

config wifi-iface

    option network  the interface you want wifi to bridge with wifi要使用的网络接口

    option device   wifi0, wifi1, wifi2, wifiN wifi设备名

    option mode     ap, sta, adhoc, monitor, mesh, or wds 操作模式,有AP、client mode、adhoc、monitor、mesh point mode(802.11s)及WDS点对点连接。

    option txpower  (deprecated) transmission power in dBm 发送功率,应设置在wifi-device。

    option ssid     ssid name SSID名字

    option bssid    bssid address 用于WDS,设置为other WDS unit的MAC地址

    option encryption none, wep, psk, psk2, wpa, wpa2 加密设置,支持none、WEP、pre-shared key、及wpa radius。

    option key      encryption key

    option key1     key 1

    option key2     key 2

    option key3     key 3

    option key4     key 4

    option passphrase 0,1 0则将WPA psk为明文passphrase,1则为encoded passphrase。可通过wpa_passphrase工具产生加密的passphrase。在passphrase包含特殊字符时有用。此选项仅适用于mac80211或atheros。

    option server   ip address radius server IP地址

    option port     port radius server端口号,缺省为1812

    option hidden   0,1 0为广播SSID,1为隐藏

    option isolate  0,1 (broadcom) 无线客户端隔离功能,0要禁止隔离,1为开启,缺省为0.

    option doth     0,1     (atheros, broadcom) Toggle 802.11h mode,0为禁止802.11h,1为启用,缺省为0.

    option wmm      0,1  (atheros, broadcom) Toggle 802.11e mode,0为禁止,1为启用,缺省为0.

Mesh Point

Mesh Point (802.11s) 仅mac80211 驱动支持,需要安装iw包来建立mesh link。Openwrt创建mshN mesh point接口,配置举例:

config wifi-device      "wlan0"

    option type            "mac80211"

    option channel      "5"

config wifi-iface

    option device       "wlan0"

    option network     lan

    option mode         "mesh"

    option mesh_id     "OpenWrt"

WDS

Wireless Distribution System

WDS是个非标准模式,可工作在同类设备间,但不能工作在不同的设备如broadcom和atheros设备间。

Unencrypted WDS connections

未加密的WDS配置如下,我们假定一端的BSSID ca:fe:ba:be:00:01,而另一端为BSSID ca:fe:ba:be:00:01:

config wifi-device      "wl0"

    option type            "broadcom"

    option channel      "5"

config wifi-iface

    option device       "wl0"

    option network     lan

    option mode         "ap"

    option ssid         "OpenWrt"

    option hidden       "0"

    option encryption   "none"

config wifi-iface

    option device       "wl0"

    option network      lan

    option mode         wds

    option ssid         "OpenWrt WDS"

    option bssid        "ca:fe:ba:be:00:02"

Encrypted WDS connections

可以加密wds连接,支持psk、psk2及psk+psk2模式,以下是一个使用AES加密算法的pre-shared key例子:

config wifi-device  wl0

    option type     broadcom

    option channel  5

config wifi-iface

    option device   "wl0"

    option network  lan

    option mode     ap

    option ssid     "OpenWrt"

    option encryption  psk2

    option key      "<key for clients>"

config wifi-iface

    option device   "wl0"

    option network  lan

    option mode     wds

    option bssid    ca:fe:ba:be:00:02

    option ssid     "OpenWrt WDS"

    option encryption   psk2

    option key      "<psk for WDS>"

802.1x configurations

       配置略

EAP-PEAP

       配置略

限制说明

Limitations

There are certain limitations when combining modes. Only the following mode combinations are supported:

WDS links can only be used in pure AP mode and cannot use WEP (except when sharing the        settings with the master interface, which is done automatically).

VAP num defaults to 4, but can be changed by loading the module with the maxvaps=N parameter.

Adding a new driver configuration

       具体添加方式略

Network-scripts.tex

Using the network scripts

为使用network,必须通过如下方式包含必须的shell脚本:

. /etc/functions.sh      # common functions

include /lib/network     # include /lib/network/*.sh

scan_interfaces          # read and parse the network config

有些协议,如PPP会在运行期间改变配置的接口名,如PPPOE会将eth0改为ppp0,因此要运行scan_interface,而不是从配置中直接读取。运行scan_interface后,ifname选项将包含有效的接口名(用于ip traffic),如果物理设备名与此不同,则会保存在device选项中。

这意味着在scan_interface后运行config_get_lan_ifname,获取的结果可能与运行之前不同。

Writing protocol handers

添加协议处理

可通过在/lib/network下添加shell脚本来定制协议处理,脚本包含:

scan_<protocolname>() {

    local config="$1"

    # change the interface names if necessary

}

setup_interface_<protocolname>() {

    local interface="$1"

    local config="$2"

    # set up the interface

}

Network.tex

     网络接口配置

网络配置文件为/etc/config/network,被分隔为多个接口配置。每一个接口配置或直接就是ethernet/wifi接口(如eth0、wl0),或包含多个接口的桥接口。

如:

config interface     "lan"

    option ifname    "eth0"

    option proto     "static"

    option ipaddr    "192.168.1.1"

    option netmask   "255.255.255.0"

    option gateway   "192.168.1.254"

    option dns       "192.168.1.254"

其中ifname指定linux接口名,如果使用bridge接口则将ifname设置为接口列表,同时添加option type “bridge”。

可通过添加vlanid来支持vlan功能如eth0.1,具体参照switch一节。

此配置是一个简单的eth0静态配置,proto指定了接口使用的协议,支持none、static、dhcp,可通过install额外的包来支持其他的协议。

Static

当为static时,ipaddr与netmask必填,而gateway与dns可选,支持多个DNS服务器,中间以空格隔开即可,如:option dns       "192.168.1.254 192.168.1.253" (optional)

如:

config interface     "lan"

    option ifname    "eth0"

    option proto     "static"

    ...

    option dns       "192.168.1.254 192.168.1.253" (optional)

DHCP

DHCP当前仅接受ipaddr与hostname选项。其中ipaddr指定了dhcp server的地址,而hostname指定了客户的的hostname标识,两者均可选。

config interface     "lan"

    option ifname    "eth0"

    option proto     "dhcp"

    option ipaddr    "192.168.1.1" (optional)

    option hostname  "openwrt" (optional)

PPPOE

PPP基础的协议,如PPPOE、PPTP支持下列选项:

Username:PPP用户名,用于PAP认证

Password:PPP密码

Keepalived:使用LCP ping PPP服务器,保活值,缺省间隔为5.

Demand:按需拨友,值指定了最大空闲时间。

Server:对端PPTP服务器IP地址

MTU设置

对所有协议,均可指定MTU,通过设置mtu选项即可,如:

config interface     "lan"

    option ifname    "eth0"

    option proto     "pppoe"

    option username  "username"

    option password  "openwrt"

    option mtu          1492 (optional)

设置静态路由

Setting up static routes

可对指定的接口添加静态路由,在接口配置后会自动添加,举例配置:

config route foo

       option interface lan

       option target 1.1.1.0

       option netmask 255.255.255.0

       option gateway 192.168.1.1

其中route节的名称可选,interface、target、gateway选项是必须的。如果netmsk不填,则默认为主机路由。

设置交换机

Setting up the switch (currently broadcom only)

设置交换机,当前仅broadcom支持。

IPV6设置

Setting up IPv6 connectivity

Init_script.tex

功能脚本

由于openwrt使用自己的初始script系统,所有的init script必须使用/etc/rc.common作为wrapper安装在/etc/init.d/<name>下。

如/etc/init.d/httpd:

#!/bin/sh /etc/rc.common

# Copyright (C) 20## OpenWrt.org

START=50

start() {

    [ -d /www ] && httpd -p 80 -h /www -r OpenWrt

}

stop() {

    killall httpd

}

从上可以看出,script本身并不解析命令行参数,而是由/etc/rc.common来完成。

Start和stop是最基本的功能,几乎所有init script都要提供。Start是在运行/etc/init.d/httpd start时来调用,可以是系统启动时,或用户手动运行此脚本时。

通过/etc/init.d/<name> enable/disable可以启用或禁止模块的初始化脚本,他是通过创建或删除/etc/rc.d中的符号连接来完成,而这些符号连接是/etc/init.d/rcS在启动阶段处理。

脚本运行的顺序是在初始脚本中通过变量START来定义,改变后需要再次运行/etc/init.d/<name> enable。

/etc/rc.common说明

#!/bin/sh                               

# Copyright (C) 20##-2011 OpenWrt.org   

                                        

. $IPKG_INSTROOT/lib/functions.sh       

. $IPKG_INSTROOT/lib/functions/service.sh

                  

initscript=$1    

action=${2:-help}  

shift 2            

                   

start() {                                

        return 0                               

}                                              

                                                

stop() {                                       

        return 0                               

}                                              

                                               

reload() {                                

        return 1                                                           

}                                                                          

                                                                           

restart() {                                                                                            

        trap '' TERM                                                                                  

        stop "$@"                                                                                      

        start "$@"                                                                                    

}                                                                                                     

                                                                                                       

boot() {                                                                                             

        start "$@"                                                    

}                                                                          

                                                                           

shutdown() {                                                               

        stop                                                                                          

}                                                                                                     

                                                                                                       

disable() {          禁止服务开启                                                                                  

        name="$(basename "${initscript}")"                                                             

        rm -f "$IPKG_INSTROOT"/etc/rc.d/S??$name                                                     

        rm -f "$IPKG_INSTROOT"/etc/rc.d/K??$name                           

}                                                                           

                                                                           

enable() {          开启服务                                                                                   

        name="$(basename "${initscript}")"                                                            

        disable                                                                                        

        [ -n "$START" -o -n "$STOP" ] || {                                                            

                echo "/etc/init.d/$name does not have a START or STOP value"                          

                return 1                                                                              

        }                                                                                             

        [ "$START" ] && ln -s "../init.d/$name" "$IPKG_INSTROOT/etc/rc.d/S${START}${name##S[0-9][0-9]}"

        [ "$STOP"  ] && ln -s "../init.d/$name" "$IPKG_INSTROOT/etc/rc.d/K${STOP}${name##K[0-9][0-9]}"

}

enabled() {                                                                                           

        name="$(basename "${initscript}")"                                                            

        [ -x "$IPKG_INSTROOT/etc/rc.d/S${START}${name##S[0-9][0-9]}" ]                               

}                                                                     

                                                                           

depends() {                                                                

        return 0                                                           

}                                                                                                      

                                                                                                      

help() {                                                                                               

        cat <<EOF                                                                                     

Syntax: $initscript [command]                                                                          

                                                                                                     

Available commands:                                                        

        start   Start the service                                           

        stop    Stop the service                                           

        restart Restart the service                                                                   

        reload  Reload configuration files (or restart if that fails)                                 

        enable  Enable service autostart                                                              

        disable Disable service autostart                                                             

$EXTRA_HELP                                                                                            

EOF                                                                                                   

}                                                                                                      

                                                                                                      

. "$initscript"          引用脚本                                                                            

                                                                     

ALL_COMMANDS="start stop reload restart boot shutdown enable disable enabled depends ${EXTRA_COMMANDS}"  所有命令,包括标准的,及定制的

list_contains ALL_COMMANDS "$action" || action=help                                                    

[ "$action" = "reload" ] && action='eval reload "$@" || restart "$@" && :'                            

$action "$@"

重载初始化脚本函数

可以通过如下方式覆盖这些标准的初始化脚本函数:

{boot()},boot时支持的命令,缺省为start。

        Commands to be run at boot time. Defaults to {start()}

{restart()} 重启动服务,缺省为stop然后再start。

        Restart your service. Defaults to {stop(); start()}

{reload()} 重新载入配置文件,缺省是restart。

        Reload the configuration files for your service. Defaults to {restart()}

定制脚本命令

也可定制命令,创建功能函数,在EXTRA_COMMANDS变量中引用,Helptext添加在EXTRA_HELP中。

如下:

status() {

    # print the status info

}

EXTRA_COMMANDS="status"

EXTRA_HELP="        status  Print the status of the service"

在/etc/rc.common中可以看出,会包含此脚本,从而包含了其中的所有定义,从而可正确地去使用。

Iw

       在openwrt中,所有无线的配置均通过iw命令来进行,如创建一个monitor 无线接口:iw phy phy0 interface add wd2j type monitor。

       Iw的设备操作可通过mac80211.sh中查看及分析。

       通过iw phy0 info可查看硬件支持信息。

      

Iw命令行

       具体参数如下:

root@OpenWrt:/lib# iw

Usage:  iw [options] command

Options:

        --debug         enable netlink debugging

        --version       show version (3.3)

Commands:

        help

        event [-t] [-r] [-f] ???

        phy

        list

        phy <phyname> info

              dev操作

        dev 列出所有dev信息

        dev <devname> info列出指定dev信息

        dev <devname> del 删除VAP

        dev <devname> interface add <name> type <type> [mesh_id <meshid>] [4addr on|off] [flags <flag>*] 添加VAP

        phy <phyname> interface add <name> type <type> [mesh_id <meshid>] [4addr on|off] [flags <flag>*]

        dev <devname> ibss join <SSID> <freq in MHz> [HT20|HT40+|HT40-|NOHT] [fixed-freq] [<fixed bssid>] [beacon-interval <TU>] [basic-rates <rate in Mbps,rate2,...>] [mcast-rate <rate in Mbps>] [key d:0:abcde]

        dev <devname> ibss leave

        dev <devname> station dump 列出关联的STA信息

        dev <devname> station set <MAC address> vlan <ifindex>

        dev <devname> station set <MAC address> plink_action <open|block>

        dev <devname> station del <MAC address>

        dev <devname> station get <MAC address>

        dev <devname> survey dump

        dev <devname> mesh leave

        dev <devname> mesh join <mesh ID> [<param>=<value>]*

        dev <devname> mpath dump

        dev <devname> mpath set <destination MAC address> next_hop <next hop MAC address>

        dev <devname> mpath new <destination MAC address> next_hop <next hop MAC address>

        dev <devname> mpath del <MAC address>

        dev <devname> mpath get <MAC address>

        dev <devname> scan [-u] [freq <freq>*] [ies <hex as 00:11:..>] [ssid <ssid>*|passive]

        dev <devname> scan trigger [freq <freq>*] [ies <hex as 00:11:..>] [ssid <ssid>*|passive]

        dev <devname> scan dump [-u]

        reg get

        reg set <ISO/IEC 3166-1 alpha2>

        dev <devname> connect [-w] <SSID> [<freq in MHz>] [<bssid>] [key 0:abcde d:1:6162636465]

        dev <devname> disconnect

        dev <devname> link

        dev <devname> offchannel <freq> <duration>

        dev <devname> cqm rssi <threshold|off> [<hysteresis>]

        phy <phyname> wowlan show

        phy <phyname> wowlan disable

        phy <phyname> wowlan enable [any] [disconnect] [magic-packet] [gtk-rekey-failure] [eap-identity-request] [4way-handshake] [rfkill-release] [patterns <pattern>*]

        dev <devname> roc start <freq> <time>

        phy <phyname> set antenna <bitmap> | all | <tx bitmap> <rx bitmap>

        dev <devname> set txpower <auto|fixed|limit> [<tx power in mBm>]

        phy <phyname> set txpower <auto|fixed|limit> [<tx power in mBm>]

        phy <phyname> set distance <distance>

        phy <phyname> set coverage <coverage class>

        phy <phyname> set netns <pid>

        phy <phyname> set rts <rts threshold|off>

        phy <phyname> set frag <fragmentation threshold|off>

        dev <devname> set channel <channel> [HT20|HT40+|HT40-]

        phy <phyname> set channel <channel> [HT20|HT40+|HT40-]

        dev <devname> set freq <freq> [HT20|HT40+|HT40-]

        phy <phyname> set freq <freq> [HT20|HT40+|HT40-]

        phy <phyname> set name <new name>

        dev <devname> set peer <MAC address>

        dev <devname> set noack_map <map>

        dev <devname> set 4addr <on|off>

        dev <devname> set type <type>

        dev <devname> set meshid <meshid>

        dev <devname> set monitor <flag>*

        dev <devname> set mesh_param <param>=<value> [<param>=<value>]*

        dev <devname> set power_save <on|off>

        dev <devname> set bitrates [legacy-<2.4|5> <legacy rate in Mbps>*]

        dev <devname> get mesh_param [<param>]

        dev <devname> get power_save <param>

You can omit the 'phy' or 'dev' if the identification is unique,

e.g. "iw wlan0 info" or "iw phy0 info". (Don't when scripting.)

Do NOT screenscrape this tool, we don't consider its output stable.

root@OpenWrt:/lib#

iw说明

更多关于iw的说明参照如下链接:

http://wireless.kernel.org/en/users/Documentation/iw

nl80211是新的802.11 netlink接口,与cfg80211一起,目的是替换无线扩展部分。nl80211与cfg80211仍在开发中。

Iw则是基于nl80211的无线设备CLI配置工具,几乎所有新的驱动均支持并加到内核中了。

Iw也仍在开发中,帮助信息可参见http://wireless.kernel.org/en/users/Documentation/iw。

对于openwrt,未和原来的SDK一样使用iwconfig及iwpriv来设置无线参数,而是使用iw命令行。同样,大多数Iwlist命令也失效了。

如下列出了iw的命令,虽然可通过这样的命令进行相关操作,但为了避免出错,建议还是使用web来进行操作,除非出于调试或测试目的。

列出所有命令行

Iw

列出所有命令及帮助

Iw help

列出设备支持能力,如带宽信息、802.11n信息

Iw list

扫描

Iw dev wlan0 scan

监听事件,调试目的

       通过监听可打印出认证、关联帧信息

Iw event

-f :显示认证、关联帧(auth/assoc/deauth/disassoc frames)

-t :显示时间戳信息

-r :显示相对时间戳(print relative timstamp)

获取链路状态(STA适用)

主要是判断是否关联到AP,适用于做为client。

Iw dev wlan0 link

建立连接

如果AP未加密或使用WEP加密,则可以通过iw来连接到此AP。

需要注意的是:当从AP断开连接时,经常出现busy的情况,需要reissue此命令。如果不想这样做,当断开时可通过wpa_supplicant来自动尝试reconnect。

假设SSID为foo的AP未加密,则可如下连接:

Iw wlan0 connect foo

假设有两个SSID为foo的AP,而我们要连接AP的频率是2432,则可如下连接:

Iw wlan0 connect foo 2432

要连接到使用WEP加密的AP

    iw wlan0 connect foo keys 0:abcde d:1:0011223344

获取STA统计信息

Iw dev wlan0 station dump

获取特定STA的统计

    iw dev wlan1 station get <peer-MAC-address>

修改transmit bitrates

    iw wlan0 set bitrates legacy-2.4 12 18 24

设置txpower

       可设置到VAP设备接口或wlan物理接口

    iw dev <devname> set txpower <auto|fixed|limit> [<tx power in mBm>]

    iw phy <phyname> set txpower <auto|fixed|limit> [<tx power in mBm>]

省电模式

开启省电模式,对mac80211驱动来讲,即打开了Dynamic Power Save。

    iw dev wlan0 set power_save on

获取省电模式配置

    iw dev wlan0 get power_save

添加接口

当前支持的接口模式有:monitor、managed(also station)、wds、mesh(also mp)、ibss(also adhoc)。

创建monitor接口

    iw phy phy0 interface add moni0 type monitor

其中moni0为接口名、monitor为模式,可替换。

当监视802.11n时,需要指定通道带宽(20或20/40MHz),对于20/40MHz要指定是upper还是lower通道。可通过如下命令设置:

iw dev <devname> set freq <freq> [HT20|HT40+|HT40-]

或:

iw phy <phyname> set freq <freq> [HT20|HT40+|HT40-]

也可指定信道而不是频率:

iw phy <phyname> set channel <channel> [HT20|HT40+|HT40-]

iw dev <devname> set channel <channel> [HT20|HT40+|HT40-]

创建一个managed模式的接口:

iw phy phy0 interface add wlan10 type managed

注意:当使用hostapd时,接口会自动转换成AP模式。

删除接口

Iw dev <moni0> del

设置频率

iw dev wlan0 set freq 2412 [HT20|HT40+|HT40-]

设置信道

iw dev wlan0 set channel 1 [HT20|HT40+|HT40-]

设置RTS

phy <phyname> set rts <rts threshold|off>

设置FRAG

phy <phyname> set frag <fragmentation threshold|off>    

修改monitor接口标识

更新regulatory domain (国家码???)

   iw reg set alpha2

其中alpha2是ISO/IEC 3166 alpha2国家码。

创建mesh 接口

设置WDS peer

为了创建WDS peer,需要首先创建WDS类型接口,然后设置peer。

iw phy phy0 interface add wds0 type wds

iw dev wds0 set peer <MAC address>

为了正常工作,驱动必须实现cfg80211回调set_wds_peer()。Mac80211实现了此回调,因此mac80211驱动只需要支持WDS类型接口即可。当发送帧时,WDS会用对端的地址替换80211头的第一个地址。

Instead of using WDS though you may want to consider using 4-address mode described below if you have control over the software running on the AP and respective clients/peers connected.

AP和client模式使用4-address

    In some situations it might be useful to run a network with an Access Point and multiple clients, but with each client bridged to a network behind it. For this to work, both the client and the AP need to transmit 4-address frames, containing both source and destination MAC addresses.

    Linux wireless has support for 4-address mode for AP and STAs but each driver needs to define this capability explicitly. All mac80211 drivers support 4-address mode if AP or STA modes of operation are supported respectively.

    On the AP side you can enable 4-address frames for individual clients by isolating them in separate AP VLANs which are configured in 4-address mode. Such an AP VLAN will be limited to one client only, and this client will be used as the destination for all traffic on its interface, regardless of the destination MAC address in the packet headers. The advantage of this mode compared to regular WDS mode is that it's easier to configure and does not require a static list of peer MAC addresses on any side.

    To enable 4-address mode when creating an interface you should add 4addr on, for example:

iw phy phy0 interface add moni0 type managed 4addr on

    In hostapd you can enable this with the flag on hostapd.conf:

wds_sta=1

wifi启动

对于7161来讲,通过测试发现,通过/sbin/wifi脚本可以启动及关闭VAP。而每一次VAP修订,均会通过wifi up来再次生效。Wifi脚本会根据VAP的配置文件来创建相应的VAP,并调用hostapd来启用无线服务功能。配置文件如:

root@OpenWrt:/sbin# cat /etc/config/wireless

config wifi-device 'radio0'

        option type 'mac80211'

        option channel '11'

        option macaddr '00:0e:8e:29:e5:98'

        option hwmode '11g'

        option txpower '27'

        option country 'CO'

config wifi-iface

        option device 'radio0'

        option mode 'ap'

        option ssid 'OpenWrt'

        option encryption 'none'

config wifi-iface

        option device 'radio0'

        option mode 'ap'

        option encryption 'none'

        option ssid 'ddd'

        option wds '1'

/etc/init.d/rcS是设备的初始化接口,首先会执行system配置文件初始化,然后对/etc/rc.d下的所有可执行初始化脚本执行start操作。

在network的脚本中会执行/sbin/wifi up,在wifi脚本中会执行wifi_updown()函数脚本,如下:

wifi_updown() {                                                     

        [ enable = "$1" ] && {                                      

                echo "wifi updown 1"                              

                wifi_updown disable "$2"                           

                scan_wifi                                    

        }                                                    

        for device in ${2:-$DEVICES}; do (                          

                echo "wifi updown 2, $device"                        

                config_get disabled "$device" disabled   

                [ 1 == "$disabled" ] && {                           

                        echo "'$device' is disabled"                

                        set disable                               

                }                                                 

                config_get iftype "$device" type             

     其中在7161上会通过调用enable_mac80211()脚本函数从而会将无线启动起来。                   

                if eval "type ${1}_$iftype" 2>/dev/null >/dev/null; then

                        echo "scan_$iftype '$device'"               

                        eval "scan_$iftype '$device'"    

                        echo "${1}_$iftype '$device'"               

                        eval "${1}_$iftype '$device'" || echo "$device($iftype): ${1} failed"

                else                                              

                        echo "$device($iftype): Interface type not supported"

                fi                                                      

        ); done                                                        

}    

设备首次启动会检测无线卡类型,检测是在/etc/rc.d中的boot脚本中:

/sbin/wifi detect > /tmp/wireless.tmp

[ -s /tmp/wireless.tmp ] && {                                                  

   cat /tmp/wireless.tmp >> /etc/config/wireless                         

}                                                                             

rm -f /tmp/wireless.tmp

wifi_detect()会遍历所支持$DRIVER列表(当前打印为prism2 mac80211),判断并执行detect_mac80211()。脚本(boot中的)会创建一个默认配置文件(sample configuration file)。每一无线驱动都有自己的配置脚本(/lib/wifi/driver_name.sh),对于7161来讲则是/lib/wifi/mac80211.sh。

hostapd的配置及启动是通过mac80211.sh来完成。在mac80211_hostapd_setup_base()中会根据当前的配置参数,写入hostapd的启动配置文件中/var/run/hostapd-phy0.conf。

enable_mac80211()中会启动hostapd,进行配置文件的实际生效,生效命令是hostapd -P /var/run/wifi-phy0.pid -B /var/run/hostap-phy0.conf。

注:

/sys/class/ieee80211/phy0/macaddress 中包括了phy0的MAC地址

root@OpenWrt:/tmp/sysinfo# cat /tmp/sysinfo/model 设备型号

Atheros PB44 reference board

root@OpenWrt:/tmp/sysinfo# cat /tmp/sysinfo/board_name  board类型

unknown

WEB设置

LuCI(Lua Configuration Interface)

    Openwrt中web页面是通过LuCI编写,这是什么东东只有上网搜索一下,此处是简单的说明。

    LuCI作为“FFLuCI”诞生于20##年3月份,目的是为OpenWrt固件从 Whiterussian 到 Kamikaze实现快速配置接口。Lua是一个小巧的脚本语言,很容易嵌入其它语言。轻量级 LUA语言的官方版本只包括一个精简的核心和最基本的库。这使得LUA体积小、启动速度快,从而适合嵌入在别的程序里。UCI是OpenWrt中为实现所有系统配置的一个统一接口,英文名Unified Configuration Interface,即统一配置接口。LuCI,即是这两个项目的合体,可以实现路由的网页配置界面。

  最初开发这个项目的原因是没有一个应用于嵌入式的免费,干净,可扩展以及维护简单的网页用户界 面接口。大部分相似的配置接口太依赖于大量的Shell脚本语言的应用,但是LuCi使用的是Lua编程语言,并将接口分为逻辑部分,如模板和视图。 LuCI使用的是面向对象的库和模板,确保了高效的执行,轻量的安装体积,更快的执行速度以及最重要的一个特性————更好的可维护性。

  与此同时,LuCI从MVC-Webframework衍生出一个包含了很多库、程序以及Lua程序用户接口的集合,但是LuCI仍然专注于实现网页用户界面并成为OpenWrt Kamikaze官方的一份子。

LuCI是一个开放源码的独立项目,欢迎任何人的加入。

Web设置

Openwrt中web是通过LuCI编写,LuCI提供了丰富的接口,而将用户的配置保存,并可通过调用linux中的脚本来进行实际应用。

因此我们猜测:

Openwrt有各模块的配置文件(在/etc/config/下),可通过web页面来修改,也可手动来修改;而对各模块的生效操作,可通过web来进行,也可手工来进行。

配置文件是各模块正确启动的依据,如果后续我们需要在openwrt基础上支持我们的产品,(1)可以直接在LuCI基础上以此为基础来写web代码;或(2)在当前代码基础上理清各模块的配置及生效接口,我们自己写web来实现。

具体可以/usr/lib/lua/luci/model/cbi/admin_network/wifi_add.lua为例。

m.uci:save("wireless") 保存配置

luci.sys.call("env -i /sbin/wifi down >/dev/null 2>/dev/null") 通过脚本来实际应用

luci.sys.call("env -i /sbin/wifi up >/dev/null 2>/dev/null")           

return os.execute("reboot >/dev/null 2>&1")  执行reboot

静态页面在:

X:\trunk\build_dir\target-mips_r2_uClibc-0.9.33\root-ar71xx\usr\lib\lua\luci\view下,即设备的\usr\lib\lua\luci\view目录。

而类似于CGI的代码则在

X:\trunk\build_dir\target-mips_r2_uClibc-0.9.33\root-ar71xx\usr\lib\lua\luci\controller\admin下,即设备的\usr\lib\lua\luci\controller\admin目录。

web小测试

将/usr/lib/lua/luci/model/cbi/admin_network下的wifi.lua删除后,页面会报如下错误:

/usr/lib/lua/luci/dispatcher.lua:449: Failed to execute arcombine dispatcher target for entry '/admin/network/wireless/radio0.network1'.

The called action terminated with an exception:

/usr/lib/lua/luci/cbi.lua:75: Model 'admin_network/wifi' not found!

stack traceback:

         [C]: in function 'assert'

         /usr/lib/lua/luci/dispatcher.lua:449: in function 'dispatch'

         /usr/lib/lua/luci/dispatcher.lua:195: in function </usr/lib/lua/luci/dispatcher.lua:194>

      

频率信道转换函数

static int nl80211_freq2channel(int freq)

{

       if (freq == 2484)

              return 14;

       if (freq < 2484)

              return (freq - 2407) / 5;

       return (freq / 5) - 1000;

}