[置顶] ifup-wlan脚本解析(wifi启动STA或是AP模式)

#ifup-wlan脚本解析 (绿色部分是注释)

/apps/etc/init.d >: vim /apps/tools/ifup-wlan

#!/bin/sh                                                           

# FILE:/usr/sbin/ifup-wlan0                                                  

# Copyright (C) 2011 GuoWenxue <[email protected] QQ:281143292>                    

# This file used to configure the specified network interface device                 

                                                                                                

source /etc/profile                                                                       

#判断目录是否存在,如果不存在,则赋值为/apps/etc/network目录。                                                                                                 

if [ -z "$network_cfg_dir" ];  then                                                       

   export network_cfg_dir=/apps/etc/network                               

fi                                                             

 

#将传入的参数赋值给DEVICE $1${1}的区别,例如:

val=10

test=${val}ue  这种情况下,是获取val变量的值,则test=10ue

text=$value    这种情况下,是获取value变量的值,这里value未定义

这两个是不一样的:

带括号的话所以{}使用来标识哪一部分是变量名

                                                                      

DEVICE=${1}                                                                                      

/********************************************************/

                                      转载声明

/********************************************************/

#下面这个是一个很巧妙的语句,关键是&&[]这个也具有判断的功能,一般执行与判断时,如果第一个判断语句是假,则不必往下执行,如果为真就会判断下一个语句。这里如果传进来的参数有不为空,即为真时,就会执行与后面的语句打印信息,并退出脚本。                                                                                                

[ -z "${DEVICE}" ] && {                                                                         

   echo $"Usage: $0 <device name>" >&2                                       

   exit 1                                                                    

                                                                                        

#下面的判断语句中-o是或的意思,查看man test

( EXPRESSION )

              EXPRESSION is true  真判定

! EXPRESSION

              EXPRESSION is false 否判定

EXPRESSION1 -a EXPRESSION2

              both EXPRESSION1 and EXPRESSION2 are true 与判定

EXPRESSION1 -o EXPRESSION2

              either EXPRESSION1 or EXPRESSION2 is true 或判定

-d  FILE

              FILE exists and is a directory  

-f  FILE

              FILE exists and is a regular file                                                                                    

if [ ! -d $network_cfg_dir -o ! -f "$network_cfg_dir/ifcfg-${DEVICE}" ]; then   

   echo "$0: configuration<$network_cfg_dir/ifcfg-${DEVICE}> not found." >&2                     

   echo "Usage: $0 <device name>" >&2                                                            

   exit 1                                                                                 

fi                                                                        

    

#判断/sys/class/net/wlan0是否存在,说明没有wlan0适配器退出                                                                   

if [ ! -d /sys/class/net/$DEVICE/ ] ; then                                                       

   echo  "Wireless network adapter $DEVICE dosn't exist, exit now..."                

   exit                                                                                         

fi                                                                                   

#其中有个“。”相当于source命令。查看

[lingyun@vmlinux fulinux]$ man source 

        .  filename [arguments]

这里是使能ifcfg-wlan0配置文件,如下:

/apps/etc/network >: vim ifcfg-wlan0 

#Wireless Network adapter RT3070(wlan0) device configure file

#FILE:/apps/etc/network/ifcfg-wlan0

# Copyright (C) 2012 GuoWenxue <[email protected] QQ:281143292>

DEVICE=wlan0

ONBOOT=yes

NAME="RT3070"

TYPE=WLAN

#The WiFi Module should work on AP or STA mode

WORKMODE=STA

#BOOTPROT should be static or dhcp, it will only take effact

#when the NIC work on STA mode

BOOTPROTO=dhcp

#Work on AP mode IP address

IPADDR_AP=192.168.5.1

NETMASK_AP=255.255.255.0

#Work on STA mode IP address

IPADDR_STA=192.168.1.166

NETMASK_STA=255.255.255.0

#Gateway Settings

GATEWAY=192.168.1.1

DEFROUTE=no

#DHCP Server configuration, only take effact when the NIC work on AP mode

DHCP_SERVER=yes

DHCP_START_IP=192.168.1.10

DHCP_END_IP=192.168.1.100

DHCP_NETMASK=255.255.255.0

DHCP_GATEWAY=192.168.1.1

DHCP_DNS1=4.2.2.2

DHCP_DNS2=8.8.8.8

DHCP_LEASE=18800

使能了这些文件后上面的一些参数就成为系统中的全局参数,比如说我在下面加入如下代码时,

cd $network_cfg_dir

. ifcfg-${DEVICE}

echo "print wifi workmode is $WORKMODE"

会打印如信息

/apps/tools >: sh ifup-wlan wlan0

print wifi workmode is STA

因为是在脚本中使能了这个文件,所以相当于创建了一个子进程,如果退出这个脚本后出来运行echo $WORKMODE不会有什么显示。                                                                              

cd $network_cfg_dir                                                                             

. ifcfg-${DEVICE}                                                                               

#由于配置文件中的WORKMODE的选项很肯使用小写的sta或是ap,也有可能是StaAp书写方法,通过下面的第一个语句就可以将这些选项统统装化为大写模式,toupper()是一个转换为大写的函数。如果不是STAstation)模式,就赋值为AP模式。                                                                                                

WORKMODE=$(echo $WORKMODE | awk '{ print toupper($0) }')                                        

if [ $WORKMODE != "STA" ] ; then                                                                 

   WORKMODE="AP"                                                                          

fi                                                                        

                                                                                                 

echo "Enable network interface $DEVICE[$NAME] work on $WORKMODE mode." >&2                       

#下面主要的是理解eval命令,可以通过在shell中拆解来理解,如下

/apps/etc/network >: export WORKMODE=STA

/apps/etc/network >: export IPADDR_STA=192.168.1.166

/apps/etc/network >: echo $WORKMODE

STA

/apps/etc/network >: echo \$IPADDR_$WORKMODE

$IPADDR_STA

/apps/etc/network >: eval "echo \$IPADDR_$WORKMODE"

192.168.1.166

/apps/etc/network >: 

也就是把192.168.1.166赋值给ipaddr,同理netmask=255.255.255.0                                                                                              

parser_ip()                                                                                      

{                                                                                                

   unset ipaddr netmask                                                              

   ipaddr=$(eval "echo \$IPADDR_$WORKMODE")                                               

   netmask=$(eval "echo \$NETMASK_$WORKMODE")                                             

}                                                                               

#下面这一个是关掉wifi适配器的函数。                                        

stop_wifi_worker()                                                                   

{                                                                                    

   #stop DHCP work on this NIC

#分解运行分析如下:

/apps/etc/network >: ps | grep dhcp

 5385 root      1332 S    udhcpc -i eth0

10678 root      1324 S    udhcpc -i wlan0

11598 root      1316 S    grep dhcp

/apps/etc/network >: ps | grep dhcp | grep -v grep

 5385 root      1332 S    udhcpc -i eth0

10678 root      1324 S    udhcpc -i wlan0

/apps/etc/network >: ps | grep dhcp | grep -v grep | grep wlan

10678 root      1324 S    udhcpc -i wlan0

/apps/etc/network >: ps | grep dhcp | grep -v grep | grep wlan | awk '{print $1}'

10678

/apps/etc/network >: ps | grep dhcp | grep -v grep | grep wlan | awk '{print $2}'

roo这样可以获得udhcpc -i wlan0的进程id,并将其杀死。下同。

                                                      

   dhcp_pid=`ps | grep -v grep | grep "dhcp" | grep $DEVICE | 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" | grep $DEVICE | awk '{print $1;}'`            

   if [ -n "$pid" ] ; then                                                                      

       kill $pid                                                                                

       sleep 1                                                                  

   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                                                                                 

       sleep 1                                                                       

   fi                                                                                           

                                                                                                

   if [ -d /var/run/hostapd ] ; then                                                            

       rm -rf /var/run/hostapd                                                                  

   fi                                                                                           

}                                                                                               

                                                                                                

#配置wifistation模式。                                                                                     

configure_wifi_sta()                                                                 

{                                                                                    

   parser_ip                                                                         

                                                                                                

   #If enable DHCP configure or IP address not configured, then use DHCP get IP address and exit

#man test 可以查看下面判断选项的意思

       -n STRING

              the length of STRING is nonzero

字符串的长度不为0为真

       STRING equivalent to -n STRING

       -z STRING

              the length of STRING is zero

字符串的长度为0为真

   -o选项是或运算

   if [ -n "$BOOTPROTO" -o -z "$ipaddr" ]; then                                                  

      BOOTPROTO=$(echo $BOOTPROTO | awk '{ print toupper($0) }')                                

      if [ "$BOOTPROTO" = "DHCP" ] ; then                                                       

          ifconfig $DEVICE up                                                                   

                                                                                     

          #Start wpa_supplicant to work now   

#连接路由命令,这里使用的配置文件是apps/etc/network/目录下的wpa_supplicant.conf                                                   

          /apps/tools/wpa_supplicant -B -Dwext -i$DEVICE -c${network_cfg_dir}/wpa_supplicant.conf

#再为我们的wifi动态分配ip地址,并且是后台运行。

          udhcpc -i $DEVICE &                                                                    

          exit                                                                                   

      fi                                                                                         

   fi                                                                                            

                                                                                                

   # Calculate the network configuration value

#如果没有上面的动态分配且不存在子网掩码,就需要分配一个                                  

   if [ -z "${netmask}" ] ; then                                                                 

     eval $(/bin/ipcalc --netmask ${ipaddr})                                                     

   fi                                                                                           

                                                                                                

   #Configure for the WiFi interface IP address and bring up it 

#静态分配ip地址和掩码。                                

   ifconfig $DEVICE $ipaddr netmask $netmask up                                                  

                                                                                     

   #Set the default route  

#DEFROUTE选项都转化为大写。                                                                     

   DEFROUTE=$(echo $DEFROUTE | awk '{ print toupper($0) }') 

#如果GATEWAY字符长度不为0DEFROUTE选项为YES时,                                   

   if [ -n "$GATEWAY" -a "$DEFROUTE" = "YES" ]; then                                             

      #ip route add  ${NETWORK}/${PREFIX} via $GATEWAY > /dev/null 2>&1                          

      ip route replace default via $GATEWAY                                                      

   fi                                                                                            

                                                                                                

   #Start wpa_supplicant to work now                                                             

   mkdir -p /var/run/wpa_supplicant                                                              

   /apps/tools/wpa_supplicant -B -Dwext -i$DEVICE -c${network_cfg_dir}/wpa_supplicant.conf       

}      

#通过将rt2070/rt3070配置为AP模式后,我们的笔记本和手机就能连接到wlan0上来,再通过netfilter/iptables构建的防火墙,使eth0接有线连接到internet上,我们的笔记本和手机就能通过它上网 -_-||

configure_wifi_ap()                                                                             

{                                                                                                

   parser_ip                                                                                     

                                                                                                 

   #Configure for the WiFi interface IP address and bring up it

#如果ipaddr长度为0,就静态分配ipaddr                                  

   if [ -z "$ipaddr" ] ; then                                                                    

      ipaddr=192.168.1.166                                                                         

      netmask=255.255.255.0                                                                      

   fi                                                                                            

   ifconfig $DEVICE $ipaddr netmask $netmask up                                                 

                                                                                          

   #Enable DHCP server  

#使能DHCP服务功能,这样我们就不用为每台连接到开发板上的电脑和手机静态分配ip地址,而是通过开发板上的DHCP服务为每一台连接的终端设备动态分配地址。                                                                        

   DHCP_SERVER=$(echo $DHCP_SERVER | awk '{ print toupper($0) }')

#如果$DHCP_SERVER 长度不为空,且$DHCP_SERVER为YES时才为真。                               

   if [ -n "$DHCP_SERVER" -a "$DHCP_SERVER" = "YES" ]; then     

#定义一些配置文件:/tmp/dhcpd_wlan0.config , /tmp/dhcpd_wlan0.leases , /var/run/dhcpd_wlan0.pid

                                

       conf_file="/tmp/dhcpd_${DEVICE}.conf"                                                    

       lease_file="/tmp/dhcpd_${DEVICE}.leases"                                                 

       pid_file="/var/run/dhcpd_${DEVICE}.pid" 

#[lingyun@localhost ~]$ ipcalc -h

ipcalc: ip address expected

Usage: ipcalc [OPTION...]

  -c, --check         Validate IP address for specified address family

  -4, --ipv4          IPv4 address family (default)

  -6, --ipv6          IPv6 address family

  -b, --broadcast Display calculated broadcast address(显示指定ip和子网掩码的广播地址)
 -h, --hostname Show hostname determined via DNS(显示指定ip的主机名)
 -m, --netmask Display default netmask for IP (class A, B, or C)(显示指定ip的子网掩码--特指默认,实际未必是)
 -n, --network Display network address(显示指定ip的网络地址)
 -p, --prefix Display network prefix(显示网络前缀)
 -s, --silent Don't ever display error messages (不显示错误信息)

Help options:

  -?, --help          Show this help message

  --usage             Display brief usage message

#[lingyun@localhost ~]$ipcalc -p 192.168.1.1 255.255.255.0
PREFIX=24
#[lingyun@localhost ~]$ipcalc -n 192.168.1.1 255.255.255.0
NETWORK=192.168.1.0
#[lingyun@localhost ~]$ipcalc -h 192.168.1.1
HOSTNAME=dbrg-2
#[lingyun@localhost ~]$ipcalc -m 192.168.1.1
NETMASK=255.255.255.0
#[lingyun@localhost ~]$ipcalc -pnbm 192.168.1.1 255.255.255.0
NETMASK=255.255.255.0
PREFIX=24
BROADCAST=192.168.1.255
NETWORK=192.168.1.0
#[lingyun@localhost ~]$

所以下面的意图是取得子网的网络地址。例如

[lingyun@localhost ~]$ ipcalc -n 192.168.5.1 255.255.255.0

NETWORK=192.168.5.0

[lingyun@localhost ~]$ ipcalc -n 192.168.5.1 255.255.255.0 | awk -F "=" '{print $2}'

192.168.5.0

[lingyun@localhost ~]$                                                                             

       DHCP_SUBNET=`ipcalc -n $DHCP_START_IP $DHCP_NETMASK | awk -F "=" '{print $ 2}`           

#下面是将子网的网络地址、子网掩码、动态分配的起止地址、域名解析、网关、租约时间(IP默认失效时间等写到/tmp/dhcpd_wlan0.config文件中,其中“>”和“>>”是重定向:

1shell遇到”>”操作符,会判断右边文件是否存在,如果存在就先删除,并且创建新文件。不存在直接创建。 无论左边命令执行是否成功。右边文件都会变为空。

2、“>>”操作符,判断右边文件,如果不存在,先创建。以添加方式打开文件,会分配一个文件描述符[不特别指定,默认为1,2]然后,与左边的标准输出  

形成下面类似的结构:

[root@localhost etc]# cat dhcpd.conf
            ddns-update-style interim;
            ignore client-updates;

            subnet 192.168.1.0 netmask 255.255.255.0 {

            # --- default gateway
            option routers                  192.168.1.1;                                                                 /*默认路由器地址*/
            option subnet-mask              255.255.255.0;                                                         /*默认子网掩码*/

            option nis-domain               "510.home";                                                             /*为客户机设置nis*/
            option domain-name              "510.home";                                                          /*客户机所属DNS域的域名*/
            option domain-name-servers      192.168.1.1;                                                      /*DNS服务器地址*/

            option time-offset              -18000;                                                                    /*为客户设置与格林威治时间的偏移时间*/
 
            option host-name        "myDhcpServer";                                                             /*设置主机名*/



            range dynamic-bootp 192.168.1.2 192.168.1.128 ;                                               /*服务器将为客户分配192.168.1.2128段内的ip*/
            default-lease-time 21600;                                                                                  /*默认地址租期,单位为s*/
            max-lease-time 43200;                                                                                     /*最长地址租期,单位为s*/

            }    

                                                                                         

       echo "subnet $DHCP_SUBNET netmask $DHCP_NETMASK { " > $conf_file                          

       echo "  range $DHCP_START_IP $DHCP_END_IP;" >> $conf_file                                 

       echo "  option domain-name-servers $DHCP_DNS1, $DHCP_DNS2;" >> $conf_file                 

       echo "  option routers $DHCP_GATEWAY;" >> $conf_file                                      

       echo "  default-lease-time $DHCP_LEASE;" >> $conf_file                                   

       echo "  max-lease-time 72000;" >> $conf_file                                              

       echo "  authoritative;" >> $conf_file                                                     

       echo "}" >> $conf_file                                                                    

       

#大多数情况下,DHCP 的安装不创建一个 dhcpd.leases 文件,在你启动 DHCP 服务器之前,你必须创建空文件 dhcpd.leases                                                                                          

       touch $lease_file                                                                         

       dhcpd -q -pf $pid_file -cf $conf_file -lf $lease_file $DEVICE    

#

-q 安静模式

-pf 指定pid_file, 这里的pid file就是程序后台运行的时候,记录这个进程的进程号是多少;

-cf指定配置文件

-lf指定lease分配的IP地址文件 

$DEVICE指定在哪个网卡上开启DHCP                         

   fi                                                                                            

#下面启动AP模式                                                                                                

   # Start hostapd to server on AP mode                                                          

   mkdir -p /var/run/hostapd                                                                     

   /apps/tools/hostapd -B ${network_cfg_dir}/hostapd.conf                                        

}                                                                                                

#真正的主题在这,上面相当于C函数,而这里相当于main函数。判断是不是STA模式,如果是就先关闭wifi,再启动STA模式,AP模式亦然                                                                                                 

if [ $WORKMODE == "STA" ]; then                                                                  

   stop_wifi_worker                                                                              

   configure_wifi_sta                                                                           

else                                                                                 

   stop_wifi_worker                                                                  

   configure_wifi_ap                                                                      

fi    

#结束

你可能感兴趣的:(dhcpd,STA,AP模式,wlan0,ifup-wlan)