基于s3c2440平台rt3070工作在AP模式

—————————————————
主机操作系统:Centos 6.5
交叉编译器环境:arm-linux-gcc-4.5.4
开发板平台: FL2440
Linux内核版本: linux-3.0
开发模块:无线网卡 RT3070.
作者:hulu<[email protected]>
—————————————————
笔者友情提醒:本文章是在fl2440开发板已经成功移植linux-3.0内核,和可读写的文件系统之上开发的,本次开发使用的是ubifs文件系统格式,且fl2440的DM9000网卡驱动和usb驱动已经成功移植,若还没成功移植DM9000网卡驱动和usb驱动的朋友请参考本人博客驱动开发部分。

此篇文章介绍如何使rt3070工作在AP无线路由器模式,并能连接外网

一、配置内核支持无线网卡softAP模式
基于s3c2440平台rt3070工作在AP模式_第1张图片

--Networking support 
      <*>RF switch subystem support  ---->   //这个一定要选上不然会出错

如果没有build in RF选项,在使用hostapd命令时会出错

~>:hostapd hostapd.conf
Configuration file:hostapd.conf
rfkill:Cannot open RFKILL control device

二、配置无线无线路由器的软件移植
2.1.移植Openssl-0.9.8e
==================================================================================================================================================
Hostapd依赖于openssl与libnl这两个库。所以首先要移植openssl与libnl,openssl我们已经移植过了,但我担心版本兼容性的问题,本着学习的心态便又移植了网上普遍使用的openssl-0.9.8e
==================================================================================================================================================

2.1.1下载Openssl-0.9.8e

Openssl-0.9.8e
http://download.csdn.net/detail/u010944778/8940135

2.1.2解压之后直接修改Makefile
这里写图片描述
基于s3c2440平台rt3070工作在AP模式_第2张图片

[hulu@centos6 openssl-0.9.8e]$ mkdir install

[hulu@centos6 openssl-0.9.8e]$ sudo make && make install

2.2移植 libnl-1.1.4
下载地址http://www.infradead.org/~tgr/libnl/
解压开始安装

[hulu@centos6 libnl-1.1.4]$ mkdir install

./configure–prefix=/home/hulu/fl2440/wifi/AP/libnl-1.1.4/install(指定安装路径) –host=arm-linux

[hulu@centos6 libnl-1.1.4]$make CC=/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc

[hulu@centos6 libnl-1.1.4]$sudo make install

在你的安装目录里边找到libnl.so.1下载到你的开发板上

2.3移植Hostapd-1.0.tar.gz
下载地址http://download.chinaunix.net/download.php?id=40061&ResourceID=4450

解压修改Makefile 和.config

[hulu@centos6 hostapd-1.0]$ cp defconfig .config

[hulu@centos6 hostapd-1.0]$ vi .config
23:CONFIG_DRICER-NL80211=Y

[hulu@centos6 hostapd-1.0]$ vi Makefile

 12 CFLAGS +=-I/home/hulu/fl2440/wifi/AP/libnl-1.1.4/install/include/
 13 CFLAGS +=-I/home/hulu/fl2440/wifi/AP/openssl-0.9.8e/install/include/
 14 LIBS +=-L/home/hulu/fl2440/wifi/AP/libnl-1.1.4/install/lib/
 15 LDFLAGS +=-L/home/hulu/fl2440/wifi/AP/libnl-1.1.4/install/lib/
 16 LIBS +=-L/home/hulu/fl2440/wifi/AP/openssl-0.9.8e/install/lib/
 17 LDFLAGS +=-L/home/hulu/fl2440/wifi/AP/openssl-0.9.8e/install/lib/

[hulu@centos6 hostapd-1.0]$ make CC=/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc

[hulu@centos6 hostapd-1.0]$sudo make install
在编译过程中出现了如下错误:
这里写图片描述
从出现的错误中可知是缺少openssl这个库,也就是我之前编译的openssl-0.9.8e有问题,我又从新编译了一下openssl-0.9.8e,成功解决此问题

将生成可执行命令hostapd和配置文件hostapd.conf
hostapd主要就在于配置文件,以下是我的基本配置:

nterface=wlan0                            //网络接口设备名称
driver=nl80211                            //默认使用nl80211无线驱动
ssid=My_wifi                              //热点名称
channel=3                                 //设定无线频道
hw_mode=g                                 //使用80211g协议标准
ignore_broadcast_ssid=0             
auth_algs=1                               //指定OSA认证算法
wpa=3                                     //指定WPA/WPA2类型
wpa_passphrase=11111111                   //指定认证密钥
wpa_key_mgmt=WPA-PSK 
wpa_pairwise=TKIP    //启用了WPA或WPA2则需要指定wpa_pairwise或rsn_pairwise
rsn_pairwise=CCMP

上面各项解释如下:
(1) ssid:无线路由器发射的wifi名称;
(2) hw_mode:指定802.11协议,包括 a = IEEE 802.11a, b = IEEE 802.11b, g = IEEE 802.11g;

===================================================================
无线局域网标准 IEEE 802.11协议
*IEEE 802.11, 1997年,原始标准(2Mbit/s,工作在2.4GHz)。
*IEEE 802.11a,1999年,物理层补充(54Mbit/s,工作在5GHz)。
*IEEE 802.11b,1999年,物理层补充(11Mbit/s工作在2.4GHz)。
*IEEE 802.11g,2003年,物理层补充(54Mbit/s,工作在2.4GHz)。
使用最多的应该是802.11n标准,工作在2.4GHz频段,可达600Mbps(理论值)

===================================================================
(3)channel:设定无线频道;

(4)interface:接入点设备名称,注意不要包含ap后缀,即如果该设备称为wlan0ap,填写wlan0即可;

(5)driver:设定无线驱动,我这里是nl80211;

(6)auth_algs=1
其中auth_algs指定采用哪种认证算法,采用位域(bit fields)方式来制定,其中第一位表示开放系统认证(Open System Authentication, OSA),第二位表示共享密钥认证(Shared Key Authentication, SKA)。我这里设置alth_algs的值为1,表示只采用OSA;

(7)wpa:指定WPA类型,这是一个位域值(bit fields),第一位表示启用WPA,第二位表示启用WPA2。在我的配置中,无论设置成1、2或3,都可以正常连接

(8)wpa_passphrase:WPA/WPA2加密需要指定密钥,这个选项就是配置WPA/WPA2的密钥。注意wpa_passphrase要求8~63个字符。另外还可以通过配置wpa_psk来制定密钥,不过要设置一个256位的16进制密钥,不适合我们的需求;

(9)wpa_pairwise/rsn_pairwise:如果启用了WPA,需要指定wpa_pairwise;如果启用了WPA2,需要指定 rsn_pairwise,或者采用wpa_pairwise的设定。

接下来将hostapd拷贝到的/bin下,并修改可执行权限,将hostapd.conf也拷贝到开发板的/app/AP/目录下
在板子上直接执行hostapd -B hostapd.conf 即可
如果编译过程出现缺少库的错误,请自行检查你hostapd所依赖的libnl库和openssl库是否成功交叉编译。
若出现读取random随机数错误,可采用符号链接的方法解决:

~> mv /dev/random /dev/random.org
~> ln -s /dev/urandom /dev/random

=========================================================================================
Linux中的随机数可以从两个特殊的文件中产生,一个是/dev/urandom.另外一个是/dev/random。上述两种方式都可以产生随机数,dev/urandom 和dev/random都是产生用不为空的随机字符流,但区别是:/dev/random设备会封锁,直到系统产生的随机字符流已经充分够用,所以耗用时间较长。/dev/urandom设备不会封锁,数据的随机程度不高,但是一般情况已经够用。

=========================================================================================
更详细的文章链接:http://www.linuxidc.com/Linux/2012-05/60476.htm

2.4.配置udhcpd
修改/opt/busybox-1.20.2/examples/udhcp/udhcpd.conf然后拷贝到开发板/etc目录下。
因为是实现最基础的功能,所以我们只要简单的修改地址池、默认网关以及dns即可。
以下是我的配置:
这里写图片描述
基于s3c2440平台rt3070工作在AP模式_第3张图片
1,修改IP池
起始IP的后两位可以随意,但必须在一个网段
192.168.x.y
192.168.x.z
2修改执行dhcp功能的接口
可以用过ifconfig -a或者iwconfig命令来查看接口
3,修改DNS、网关、netmask等
opt dns 8.8.8.8 # DNS地址
option subnet 255.255.255.0 #子网掩码
opt router 192.168.2.1 #网关
其他默认即可

2.4.1 自动分配IP链接wif
因为udhcpd和udhcpc一样都是busybox里面自带的命令。所以我直接把配置文件放到开发板上再执行命令

~> ifconfig wlan0 192.168.2.1 netmask 255.255.255.0 (先把要接入点设备ip设置好)
~>udhcpd -f /etc/udhcpd.conf //就可以启动dhcp服务器了。
(注意!!!)这里执行的时候可能会出错!!!
udhcpd -f /etc/udhcpd.conf
udhcpd (v1.20.2) started
udhcpd: can’t open ‘/var/lib/misc/udhcpd.leases’: No such file or directory

Udhcpd在执行的时候可能会提示没有一个叫做udhcpd.release的租赁文件,这个只要在相应的文件夹下创建即可。执行下面两条命令:

~>mkdir -p /var/lib/misc/
~>touch /var/lib/misc/udhcpd.leases
再次执行!
~>udhcpd -f /etc/udhcpd.conf
udhcpd (v1.20.2) started
Sending OFFER of 192.168.2.20
Sending ACK to 192.168.2.20
Sending ACK to 192.168.2.20
Sending ACK to 192.168.2.20

2.5 iptables移植

===============================================================================
ptables简介:
iptables是基于内核的防火墙,功能非常强大,iptables内置了filter,nat和mangle三张表。

五个规则链。
1.PREROUTING (路由前)
2.INPUT (数据包流入口)
3.FORWARD (转发管卡)
4.OUTPUT(数据包出口)
5.POSTROUTING(路由后)

Filter表负责过滤数据包,包括的规则链有,input,output和forward;
Nat表则涉及到网络地址转换,包括的规则链有,prerouting,postrouting和output;
Mangle表则主要应用在修改数据包内容上,用来做流量整形的。
默认的规则链有:INPUT,OUTPUT,NAT,POSTROUTING,PREROUTING;
INPUT匹配目的IP是本机的数据包,FORWARD匹配流经本机的数据包,PREROUTING用来修改目的地址用来做DNAT,POSTROUTING用来修改源地址用来做SNAT。
===============================================================================

2.5.1下载
iptables-1.4.12.tar.gz

http://download.csdn.net/detail/u010944778/8945513

2.5.2解压之后进入目录

[hulu@centos6 iptables-1.4.12]$  mkdir install

[hulu@centos6 iptables-1.4.12]$./configure --host=arm-linux --enable-static --disable-shared --prefix=/home/hulu/wifi/AP/iptables-1.4.12/install --disable-ipv6 --disable-largefile

[hulu@centos6 iptables1.4.12]$makeCC=/opt/buildroot2012.08/arm920t/usr/bin/arm-linux-gcc CFALGS=--static LDFLAGS=-static

[hulu@centos6 iptables-1.4.12]$sudo make install

========================================================================================================
再理解一次CFLAGS和LDFLAGS:一般我们通过CFLAGS的 -I 选项告诉编译器所依赖的第三方的库的头文件在哪里,通过LDFLAGS的-L选项告诉链接器这些库的库文件在哪里;还有LIBS是告诉链接器要链接哪些库文件。简单地说,LDFLAGS是告诉链接器从哪里寻找库文件,而LIBS是告诉链接器要链接哪些库文件。有时候LIBS指定了却找不到库时可以试试LDFLAGS。

========================================================================================================

[hulu@centos6 iptables-1.4.12]$ cd ./install/sbin

[hulu@centos6 iptables-1.4.12]$ file *

[hulu@centos6 iptables-1.4.12]$ sudo /opt/buildroot2012.08/arm920t/usr/bin/arm-linux-strip xtables-multi

strip的作用是减轻点重量
此时将/install/lib文件夹下的文件都拷贝到开发板的/lib目录下,并赋予可执行权限,将xtables-multi放到开发板的/bin目录下,赋予可执行权限后将xtables-multi改名为iptables

有了iptables命令工具之后我们便要来配置nat转发表,如下:

~> iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables v1.4.2: can’t initialize iptables table `nat’: Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.

怎么会出现以上错误,百度了一下,原来是内核有的选项没选上,解决如下:
配置内核选项

Networking —->
  Networking options —->
  [*] Network packet filtering (replaces ipchains)  —>
    Core Netfilter Configuration  —>
      <*> Netfilter Xtables support (required for ip_tables)
    IP: Netfilter Configuration —>
      <*> Connection tracking (required for masq/NAT)
      <*> IP tables support (required for filtering/masq/NAT)
      <*>   IP range match support
      <*>   Packet filtering
      <*>     REJECT target support
      <*>   Full NAT

将新编译的内核在烧到开发板上,在重新配置配置nat转发表:

/*将局域网内地址通过eth0接口伪装后转发出去*/
~>:iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
/*开启转发功能,允许已建立连接及相关连接对内转发*/
~>: iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISH -j ACCEPT 
/*对外转发,数据包从wlan0流向eth0*/
~>: iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT 

iptables主要参数
iptables定义规则的方式比较复杂:
格式:iptables [-t table] COMMAND chain CRETIRIA -j ACTION
-t table :3个filter nat mangle
COMMAND:定义如何对规则进行管理
chain:指定你接下来的规则到底是在哪个链上操作的,当定义策略的时候,是可以省略的
CRETIRIA:指定匹配标准
-j ACTION :指定如何进行处理

A 向规则链中添加一条规则,默认被添加到末尾
-T指定要操作的表,默认是filter
-D从规则链中删除规则,可以指定序号或者匹配的规则来删除
-R进行规则替换
-I插入一条规则,默认被插入到首部
-F清空所选的链,重启后恢复
-N新建用户自定义的规则链
-X删除用户自定义的规则链
-p用来指定协议可以是tcp,udp,icmp等也可以是数字的协议号,
-s指定源地址
-d指定目的地址
-i进入接口
-o流出接口
-j采取的动作,accept,drop,snat,dnat,masquerade

详情可以参考http://www.cnblogs.com/argb/p/3535179.html这篇文章

=======================================================================================================================================================
关于iptables的nat参考:

MASQUERADE是SNAT网络地址转换的一种,SNAT的使用方法,即可以NAT成一个地址,也可以NAT成多个地址,但是,对于SNAT,不管是几个地址,必须明确的指定destination的ip.如果eth0是动态拨号获取IP,那就需要MASQUERADE来实现SNAT。而我的eth0是接到路由器VAN上的,虽然路由器是拨号上网,但是我的eth0是自己指定的IP,每次都不会变,所以应该也可以使用SNAT的方式来配置iptables。不过我觉得MASQUERADE更方便,这就当为3G动态拨号直连做预热吧。
=======================================================================================================================================================

开启linux 的转发功能! Linux系统是默认进制数据包转发的,所谓的转发就是当主机拥有多块网卡的时候,其中一块收到数据包,根据数据包的目的ip转发到本机的另一张网卡上,该网卡根据路由表继续发送数据包首先保证硬件连通,然后打开系统的转发功能
less /proc/sys/net/ipv4/ip_forward,该文件内容为0,表示禁止数据包转发,1表示允许,将其修改为1。可使用命令echo “1” > /proc/sys/net/ipv4/ip_forward 修改文件内容,重启网络服务或主机后效果不再生效

查看是否已打开 ip 转发(1 表示打开):

~>cat /proc/sys/net/ipv4/ip_forward
如果未打开,则用以下命令打开:
~>echo “1”>/proc/sys/net/ipv4/ip_forward

在以上都准备就绪后,我们一定要记得先实现eth0能上网,eth0要上网的话我们只要再给网关和DNS就可以了。

~>route add default gw 192.168.1.1 //设置默认网关为192.168.1.1;只有eth0联网,这个缺省就行。

至于DNS,linux系统并没有直接配置DNS的命令行。网上都说在/etc/resolv.conf中修改,我们回顾STA模式DHCPC自动分配IP的时候打印信息也有个recreating /etc/resolv.conf因为我在做根文件系统的时候并没有在/etc目录下创建resolv.conf,于是我又到文件系统目录树里面创建了一个。在新建的resolv.conf里面添加nameserver:114.114.114.114 //DNS

然后连上的wifi热点就可以上网了。至此使用hostapd+udhcpd+iptables等工具基于内核mac80211驱动框架就实现了RT3070无线网卡的softAP!!!

以下是我编写同时实现rt3070的sta模式和ap模式的脚本文件,读者可适当参考,若是看不懂,请参考关于shell脚本语法http://tsov.net/sh-script-syntax/

#!/bin/sh                                      
#Copyright (C) 2015 hulu<1334528355qq.com>                         
#This script is used to start Wifi                                                

export sta=/apps/wireless/sta                                                     
export AP=/apps/wireless/ap                                                            


read -p "choice Wifi mode(sta or ap):" mode                                            
echo "Worked on $mode now"                              

DEVICE=${1}                                             
dhcp=${2}                                                                              

#    cp $sta/libcrypto.a          /lib                                                 
#    cp $sta/libcrypto.so.0.9.8   /lib                                                 
#    cp $sta/libssl.so.0.9.8      /lib                                                 
#    cp $sta/libssl.a             /lib                                                 
#    cp $sta/wpa_supplicant       /bin                                                 
#    cp $sta/wpa_cli              /bin                                                 
#    cp $sta/wpa_passphrase       /bin                                                 

#    chmod 777  wpa*                                

#    mkdir -p                     /lib/firmware                    
#    cp $sta/rt2870.bin           /lib/firmware                    

configure_wifi_sta()                                                    
{                                                                                 
    ifconfig wlan0 up                                                                  
    wpa_supplicant -B -d -Dwext -iwlan0 -c $sta/wpa_supplicant.conf                    
    #ifconfig wlan0 192.168.0.120 broadcast 192.168.0.255 netmask 255.255.255.0 up     

#    cp $sta/default.script /usr/share/udhcpc/                          
#    chmod 777 default.script                                           

   if [ "$dhcp" = "dhcp" ]; then                                        
     udhcpc -i wlan0                                                    
   fi                                                                   

    ifconfig eth0 down                                                  
    echo "now wifi is active,you can internet."                                        
}                                                                                      




#    mkdir /lib/firmware                                                               
#    cp /apps/wireless/sta/rt2870.bin /lib/firmware/             

configure_wifi_ap()                                                     
{                                                                       
    mv /dev/random /dev/random.org  
ln -s /dev/urandom /dev/random                                                

    mkdir -p /var/lib/misc/                                                       
    touch /var/lib/misc/udhcpd.leases                                                  

    ifconfig wlan0 192.168.2.1                                                         
    ifconfig eth0 192.168.0.120 netmask 255.255.255.0 up                               
    route add default gw 192.168.0.1                               

#    cp $AP/libnl.so.1        /lib                                                     
    hostapd -B $AP/hostapd.conf                                                        

    if [ "$dhcp" = "dhcp" ]; then                                                      
      udhcpd  /etc/udhcpd.conf                                                         
    fi                                                                                 

    iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE                               
    iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
    iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT                                     

    echo "1" >/proc/sys/net/ipv4/ip_forward                                       
    echo "now ap is active."                                                      
}                                                                                 


stop_wifi()                                                             
{                                                                                 
    #stop DHCP work on this NIC                                                        

    dhcp_pid=`ps | grep -v grep | grep "udhcp" | awk '{print $1;}'`                    
    if [ -n "$dhcp_pid" ]; then                                                        
    kill $dhcp_pid                                                      
    fi                                                                  

    ifconfig $DEVICE 0.0.0.0                                            

    #Stop wpa_supplicant work on STA mode                                              

     pid=`ps | grep -v grep | grep "wpa_supplicant" | awk '{print $1;}'`
     if [ -n "$pid" ]; then                                                            
     kill $pid                                                                         
     fi                                                                                

    if [ -d /var/run/wpa_supplicant ]; then                                            
    rm -rf /var/run/wpa_supplicant                                                     
    fi                                                                                 

     #Stop hostapd work on AP mode                                                     

     pid=`ps | grep -v grep | grep "hostapd" | awk '{print $1;}'`       
     if [ -n "$pid" ]; then
     kill $pid                                                          
     fi                                                                 

}                                                                                      

#begin!!!!!!!!                                                                         
if [ $mode = ap ]; then                                                                
 stop_wifi                                                                             
 configure_wifi_ap                                                                     
else                                                             
 stop_wifi                                                                             
 configure_wifi_sta                                                                    
exit                                                                    
fi           

你可能感兴趣的:(rt3070)