嵌入式设备的网络设置主要是靠一些命令进行处理的:
#MAC地址设置
ifconfig eth0 down
ifconfig eth0 hw ether $MACADDR
ifconfig eth0 up
ifconfig eth0 $ip netmask $netmask #IP 和子网掩码设置
route add default gw $gatewayip #网关设置
ifconfig lo $localhost #本机设置
通过一个脚本来实现设置功能。
其中需对输入进行详细的检测,判断是否为可用网络配置。
检查项有:
这里涉及到一些网络工程基础知识,例如,子网,网关。
计算机在发送数据报的时候,由于数据链路层只负责MAC(Media Access Control 媒体访问制)地址,而IP地址是网络层负责的,因此需要ARP(Address Resolution Protocol)来维护,当需要发送一个数据报给某个IP时,本机会从建立的对照表中查询对应的MAC地址来发送,此时如果本机IP和目标IP同网(两个IP与子网掩码的与(&)值相同),则直接发送数据报,而不同的话,则将数据报发往网关IP对应的主机,由路由代发。
首先IP是由4段8位二进制数表示,每一段为8位(每位是0或1),占一个字节,因此每一段大小从0到255.
子网掩码由32位(每位可以是0或1,规则上,高位必须有连续的若干个1,低位必须全为0)表示,分为网络地址段和主机地址段。网络地址段就是子网(Subnet),同一子网(Subnet)是使用相同的网关,32位中,前面全是1的部分即为子网覆盖的区间,后面0的部分就代表主机部分。例如一个子网掩码为255.255.192.0, 换成32位二进制表示:11111111 11111111 11000000 00000000, 即可容纳的主机数就是后面0的个数表示的大小,2^14 - 1 = 16383。
因此 255.255.255.254 的子网掩码就意味着只有一个主机数,这条规则也应用于检测。
为什么说同一网络段使用相同的网关,是因为网关是由IP和子网掩码的二进制与运算得来的。即在做网关可用性检测时,就利用(IP & netmask)== (GW & netmask)来判断。
IP冲突检测可以用ping加arp指令:
## $conflict 为空则IP不冲突,否则会得到arp缓存中的信息。
conflict=`ping -c 2 -t 1 $TMP_IP_INPUT >/dev/null 2>&1 && arp -a $TMP_IP_INPUT`
有了上述约束条件,加上各种设置失败的异常处理(还原现场),脚本就完成了。
shell 笔记:
脚本中对输入参数的处理是多种多样的,这里使用了getopt来处理。
option=`getopt -l help -l init -- nhim: "$@"` 2> /dev/null
eval set -- "$option"
while true
do
case $1 in
-h|--help)
#usage
usage_Func
break;
;;
-n)
#设置完后系统不重启
SYS_REBOOT_ENABLE=$SYS_REBOOT_OFF
shift 1
;;
-m)
#设置MAC地址,且接收MAC地址到变量MACADDR
MAC_SET_ENABLE=$MAC_SET_ON
MACADDR=$2
shift 2
;;
-i|--init)
#此选项用于系统启动时设置网络配置。
INIT_CONFIG_NET_ENABLE=1
shift 1
;;
--)
# usage_Func
shift
break;
;;
*)
# usage_Func
shift
break;
;;
esac
done
特殊变量列表
变量 含义
- $0 当前脚本的文件名
- $n 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。
- $# 传递给脚本或函数的参数个数。
- $* 传递给脚本或函数的所有参数。
- $@ 传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到。
- $? 上个命令的退出状态,或函数的返回值。一般情况下,大部分命令执行成功会返回 0,失败返回 1。
- $$ 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。
- $* 和 $@ 的区别
- $* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。
- 但是当它们被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。
网络配置由一个ini配置文件管理。INI文件由节、键、值组成。
例如:
[NETWORK]
ipaddr=172.16.0.xx
netmask=255.255.255.0
gateway=172.16.0.1
macaddr=xxxxxx
读取INI配置文件中的值:
read_ini=`awk -F '=' '/\['$SECTION'\]/{a=1}a==1&&$1~/'$ITEM'/{print $2;exit}' $INIFILE`
#eg:ip=`awk -F '=' '/\['NETWORK'\]/{a=1}a==1&&$1~/'ipaddr'/{print $2;exit}' $INIFILE`
更改INI配置文件中的值:
sed '/^'"$ITEM"'/{ s~^.*$~'"$ITEM"'='"$VALUE"'~g }' -i "$INIFILE"