AutoIP 的嵌入式應用

背景

開發的產品需要增加 AutoIP 功能,具體要求如下:

  1. 當設置爲 DHCP 時,如果 DHCP 獲取或續約失敗,則啓用 AutoIP 獲取 IP 地址

  2. AutoIP 期間,DHCP 一旦成功則切換到 DHCP 獲得的 IP 地址

介紹 Zeroconf

Zeroconf 全稱爲 Zero configuration networking,提出者是 Apple 公司,中文名則爲零配置網絡規範,是一種用於自動生成可用 IP 地址的網絡技術,不需要額外的手動配置和專屬的配置服務器

“零配置網絡服務”的目標,是讓非專業用戶也能便捷的連接各種網絡設備,例如計算機、打印機等。整個搭建網絡的過程都是通過程序自動化完成
如果沒有 Zeroconf,用戶必須手動配置一些服務,例如 DHCP、DNS、計算機網絡的其它設置等。這些對非技術用戶和新用戶們來說是很難的事情

很多 Linux 發行版都默認安裝該服務,當系統無法連接 DHCP server 的時候,就會嘗試通過 Zeroconf 來獲取 IP

舉個例子:
用戶擁有一臺 Apple TV 和一臺 iPhone X,它們只要都連入到同一個無線局域網內,iPhone X 就會自動找出 Apple TV,那麼在播放音樂或者視頻的時候,用戶只要點擊推送,就可以將音樂和視頻推送到 Apple TV 上播放

Zeroconf 既然是協議,因此對應的是各種產品的實現,現在最主要的實現是 Apple 公司的 Bonjour 和開源的 Avahi

介紹 Avahi

Avahi 是 Zeroconf 規範的開源實現,基本是使用在 Linux 和 FreeBSD 上。包含了一整套多播 DNS(multicast DNS)/DNS-SD 網絡服務的實現,使用的發佈授權是 LGPL。在程序接口上,它使用 DNSD 與 Apple 的 Bonjour 進行兼容,方便原來使用 Bonjour 的產品進行遷移
目前在絕大多數的 Linux 發行版本中,都將 Avahi 作爲系統啓動進程,並且大量的服務也依賴於avahi
Avahi 也是用純 C 編寫的,同樣也可以使用諸如 Java 語言去調用

Avahi 允許程序在不需要進行手動配置網絡的情況下,在一個本地網絡中發佈和獲知各種服務和主機。例如,當某用戶把他的計算機接入到某個局域網時,如果他的計算機運行有 Avahi 服務,則 Avahi 程序就會自動廣播,從而發現網絡中可用的打印機、共享文件和可相互聊天的其他用戶

接下來介紹在嵌入式怎麼使用 Avahi …

軟件包

下載所需的軟件包,avahi 需要依賴:

  1. expat,用於解析 XML 文件的 ( --with-xml=expat )
  2. libdaemon,編譯 avahi 必須的包,用於支持 avahi-daemon ( --enable-libdaemon )

http://distfiles.macports.org/expat/expat-2.1.0.tar.gz
http://distfiles.macports.org/libdaemon/libdaemon-0.14.tar.gz
http://distfiles.macports.org/avahi/avahi-0.6.31.tar.gz

例如,按照下圖的文件組織結構擺放好,編譯生成的頭文件和庫文件設定存放在 out 目錄
在這裏插入圖片描述

交叉編譯

先來看 expat,Makefile 如下,配置自己的交叉工具鏈,沒什麼需要特別注意的

export CROSS_COMPILE ?= arm-linux-
export CC      := $(CROSS_COMPILE)gcc
export CXX     := $(CROSS_COMPILE)g++
export AR      := $(CROSS_COMPILE)ar
export RANLIB  := $(CROSS_COMPILE)ranlib
export LD      := $(CROSS_COMPILE)ld
export STRIP   := $(CROSS_COMPILE)strip
export OBJCOPY := $(CROSS_COMPILE)objcopy
NAME = expat-2.1.0
PREFIX_DIR = $(shell pwd)/../out
default: clean
	make install
clean:
	rm -rf $(NAME)
unpack: clean
	tar xzvf $(NAME).tar.gz
config: unpack
	cd $(NAME) && ./configure\
		--host=arm-linux\
		--build=i686-linux\
		--prefix=$(PREFIX_DIR)
build: config
	make -C $(NAME)
install: build
	make -C $(NAME) install

其次是 libdaemon

export CROSS_COMPILE ?= arm-linux-
export CC      := $(CROSS_COMPILE)gcc
export CXX     := $(CROSS_COMPILE)g++
export AR      := $(CROSS_COMPILE)ar
export RANLIB  := $(CROSS_COMPILE)ranlib
export LD      := $(CROSS_COMPILE)ld
export STRIP   := $(CROSS_COMPILE)strip
export OBJCOPY := $(CROSS_COMPILE)objcopy
NAME = libdaemon-0.14
PREFIX_DIR = $(shell pwd)/../out
default: clean
	make install
clean:
	rm -rf $(NAME)
unpack: clean
	tar xzvf $(NAME).tar.gz
config: unpack
	echo "ac_cv_func_setpgrp_void=yes" > $(NAME)/config.cache
	cd $(NAME) && ./configure\
		--host=arm-linux\
		--build=i686-linux\
		--config-cache\
		--prefix=$(PREFIX_DIR)\
		--disable-lynx
build: config
	make -C $(NAME)
install: build
	make -C $(NAME) install

再到 avahi,需要注意的是第 49 行,要加上prefix=""纔行,否則運行不起來
運行 avahi 進程的時候,需要一個配置文件叫 avahi-autoipd.action
prefix=""表示配置文件的路徑是在 /etc/avahi/avahi-autoipd.action

export CROSS_COMPILE ?= arm-linux-
export CC      := $(CROSS_COMPILE)gcc
export CXX     := $(CROSS_COMPILE)g++
export AR      := $(CROSS_COMPILE)ar
export RANLIB  := $(CROSS_COMPILE)ranlib
export LD      := $(CROSS_COMPILE)ld
export STRIP   := $(CROSS_COMPILE)strip
export OBJCOPY := $(CROSS_COMPILE)objcopy
NAME = avahi-0.6.31
PREFIX_DIR = $(shell pwd)/../out
default: clean
	make install
clean:
	rm -rf $(NAME)
unpack:
	tar xzvf $(NAME).tar.gz
config: unpack
	cd $(NAME) && ./configure\
		--host=arm-linux\
		--build=i686-linux\
		--prefix=$(PREFIX_DIR)\
		--disable-dbus\
		--disable-gdbm\
		--disable-glib\
		--disable-gobject\
		--disable-gtk\
		--disable-gtk3\
		--disable-manpages\
		--disable-monodoc\
		--disable-python\
		--disable-qt3\
		--disable-qt4\
		--enable-libdaemon\
		--with-distro=none\
		--with-xml=expat\
		--with-avahi-user=root\
		--with-avahi-group=root\
		--with-autoipd-user=root\
		--with-autoipd-group=root\
		CC=$(CC)\
		CXX=$(CXX)\
		LD=$(LD)\
		RANLIB=$(RANLIB)\
		CFLAGS="-I$(PREFIX_DIR)/include"\
		CXXFLAGS="-I$(PREFIX_DIR)/include"\
		LDFLAGS="-L$(PREFIX_DIR)/lib"\
		PKG_CONFIG_PATH="$(PREFIX_DIR)/lib/pkgconfig"
build: config
	make -C $(NAME) prefix=""
install: build
	make -C $(NAME) install

最後到最外層的 Makefile,統攬全局,只需在最外層敲一個make就可以編譯完

PREFIX_DIR = $(shell pwd)/out
default: clean
	test -z $(PREFIX_DIR) || mkdir -p $(PREFIX_DIR)
	make -C expat
	make -C libdaemon
	make -C avahi
clean:
	make -C expat clean
	make -C libdaemon clean
	make -C avahi clean

準備環境

一塊開發板、一個交換機、一個路由器,按下圖連接好
在這裏插入圖片描述

爲了能快速驗證 autoip 的功能,我們把路由器的 DHCP 租約時間設置爲最小,本實驗所用路由器最小租約時間是 2 分鐘
正常的時候,PC 和開發板都是可以上外網的,當然也可以互相 ping 通

正常時 PC 的 IP 信息如下
在這裏插入圖片描述

正常時開發板的 IP 信息如下
在這裏插入圖片描述

實驗

把 out/lib 目錄的動態庫文件拷貝到開發板的 /lib 目錄
在這裏插入圖片描述

把 out/sbin 目錄的可執行文件拷貝到開發板的 /sbin 目錄
在這裏插入圖片描述

在開發板運行avahi-autoipd -h查看幫助文檔可知,需要一個腳本
在這裏插入圖片描述

把 out/etc/avahi 目錄的配置文件 avahi-autoipd.action 拷貝到開發板的 /etc/avahi 目錄

運行 avahi-autoipd,命令是:
/sbin/avahi-autoipd -D eth0 --script=/etc/avahi/avahi-autoipd.action

這時候,拔掉上面連接圖的紅色這根網線,然後等待 2 分鐘左右,開發板會去請求 DHCP 續租,但是網線已被我們拔掉,請求已經達到不了路由器這邊了,所以這時候 autoip 會自動獲取一個 169.254.xxx.xxx 的地址,ifconfig 看到的地址信息如下圖
在這裏插入圖片描述

再看 PC 這邊的地址信息,因爲 PC 本身就內置了 Zeroconf 協議的實現,所以 PC 也會拿到一個 169.254.xxx.xxx 的地址,如下圖
在這裏插入圖片描述

此時,PC 和 開發板之間依然可以進行通信,因爲他們還在一個局域網裏頭

參考資料

https://www.xuebuyuan.com/3195396.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章