Ubuntu avahi-daemon 移植 arm-linux(arm-linux-gnueabihf)

mDNS 協議介紹

mDNS 原理的簡單理解——每個進入局域網的主機,如果開啟了 mDNS 服務的話,都會向局域網內的所有主機組播一個消息,我是誰,和我的 IP 地址是多少。然後其他也有該服務的主機就會響應,也會告訴你,它是誰,它的 IP 地址是多少。

mDNS multicast DNS , 使用 5353 端口,組播地址 224.0.0.251。在一個沒有常規 DNS 服務器的小型網絡內,可以使用 mDNS 來實現類似 DNS 的編程接口、包格式和操作語義。 MDNS 協議的報文與 DNS 的報文結構相同,但有些字段對於 MDNS 來說有新的含義。

每個進入局域網的主機,如果開啟了 mDNS 服務的話,都會向局域網內的所有主機組播一個消息,我是誰,和我的 IP 地址是多少。然後其他也有該服務的主機就會響應,也會告訴你,它是誰,它的 IP 地址是多少。 mDNS 的域名與普通 DNS 的域名是通過後綴.local 區分開來的。如果一台終端需要訪問一個 mDNS 域名,他就會向局域網內發送組播,詢問該域名的 IP 是多少。

例如:

一個設備接入網絡,首先查詢名稱是否衝突,並通告當前服務器信息 衝突檢測結束後,發送 MDNS 通告,通知其它設備更新 DNS 緩存 其它設備對該域名訪問時,會發起 MDNS 查詢

移植 avahi 到 arm-linux

準備好要使用的 toolchain

1.下載 3 個 tar 包

自行解壓縮到指定資料夾,本文示範如下

$ tree -L 1 ~/Desktop/avahi-daemon-XXXXX/
/home/yuyan/Desktop/avahi-daemon-XXXXX/
├── avahi-0.7
├── expat-2.2.9
├── libdaemon-0.14
└── attr-2.5.1

4 directories, 0 files

2.編譯 libdaemon

#unpackge libdaemon
$tar zxvf libdaemon-0.14.tar.gz
$cd libdaemon

#切換至管理員
$sudo -s

#連接toolchain
$export PATH=$PATH:/opt/toolchains/ti335x/i686-arago-linux/usr/bin

#build libdaemon
$./configure \
--host=arm-linux-gnueabihf \
--prefix=/opt/ARMv7_ti335x/libdaemon \
--disable-shared \
CC=arm-linux-gnueabihf-gcc \
--config-cache \
ac_cv_func_setpgrp_void=yes  # <====放入這行可以直接避掉錯誤

(...)
# 發生錯誤
checking whether setpgrp takes no argument... configure: error: cannot check setpgrp when cross compiling
...
#修正錯誤
$echo "ac_cv_func_setpgrp_void=yes" > config.cache
$./configure \
--host=arm-linux-gnueabihf \
--prefix=/opt/ARMv7_ti335x/libdaemon \
--disable-shared \
CC=arm-linux-gnueabihf-gcc \
CFLAGS="-I/opt/toolchains/ti335x/cortexa8t2hf-vfp-neon-linux-gnueabi/usr/include -L/opt/toolchains/ti335x/cortexa8t2hf-vfp-neon-linux-gnueabi/lib" \
--config-cache

$make
$sudo make install

3.編譯 expat (如果 toolchain 沒有的話)

#解壓縮
$bzip2 -d expat-2.2.9.tar.bz2ls
$tar xvf expat-2.2.9.tar./

#切換至管理員
$sudo -s

#連接toolchain
$export PATH=$PATH:/opt/toolchains/ti335x/i686-arago-linux/usr/bin

$./configure \
--host=arm-linux-gnueabihf \
--prefix=/opt/ARMv7_ti335x/expat-2.2.9 \
--enable-shared=no \
CC=arm-linux-gnueabihf-gcc \
CFLAGS="-I/opt/toolchains/ti335x/cortexa8t2hf-vfp-neon-linux-gnueabi/usr/include -L/opt/toolchains/ti335x/cortexa8t2hf-vfp-neon-linux-gnueabi/lib"
$make
$make install

4.編譯 libattr (如果 toolchain 沒有的話)

(20220718 補充) 編譯流程跟expat差不多 <= 有需要調整請自行修正

#解壓縮
$tar zxvf attr-2.5.1.tar.gz

#讓root帳號辨別toolchain位置
$sudo -s
$export PATH=$PATH:/opt/toolchains/ti335x/i686-arago-linux/usr/bin
$./configure --host=arm-linux-gnueabihf --prefix=/opt/ARMv7_ti335x/attr CC=arm-linux-gnueabihf-gcc
$make
$make install

5.編譯 avahi

這邊目的只在於編譯 avahi-daemon,所以其他的工具都會 disable。

Optional Features:

opertion description
–disable-option-checking ignore unrecognized –enable/–with options
–disable-FEATURE do not include FEATURE (same as –enable-FEATURE=no)
–enable-FEATURE[=ARG] include FEATURE [ARG=yes]
–enable-silent-rules less verbose build output (undo: “make V=1”)
–disable-silent-rules verbose build output (undo: “make V=0”)
–enable-dependency-tracking do not reject slow dependency extractors
–disable-dependency-tracking speeds up one-time build
–disable-stack-protector Disable GCC’s/libc’s stack-smashing protection
–enable-shared[=PKGS] build shared libraries [default=yes]
–enable-static[=PKGS] build static libraries [default=yes]
–enable-fast-install[=PKGS] optimize for fast installation [default=yes]
–disable-libtool-lock avoid locking (might break parallel builds)
–disable-nls do not use Native Language Support
–disable-rpath do not hardcode runtime library paths
–disable-glib Disable use of GLib
–disable-gobject Disable use of GLib GObject
–enable-introspection=[no/auto/yes] Enable introspection for this build
–disable-libevent Disable use of libevent
–enable-qt3 Enable building of Qt3 mainloop integration
–disable-qt4 Disable building of Qt4Core mainloop integration
–disable-qt5 Disable building of Qt5Core mainloop integration
–disable-gtk Disable use of GTK+ 2
–disable-gtk3 Disable use of GTK+ 3
–disable-dbus Disable use of D-Bus
–enable-dbm Enable use of DBM
–disable-gdbm Disable use of GDBM
–disable-libdaemon Disable use of libdaemon
–disable-python Disable scripts that depends on python
–disable-pygobject Disable use of Python GObject
–disable-python-dbus Disable use of D-Bus in Python
–disable-mono Disable mono bindings
–disable-monodoc Disable documentation for mono bindings
–disable-autoipd Disable building of avahi-autoipd
–disable-doxygen-doc don’t generate any doxygen documentation
–disable-doxygen-dot don’t generate graphics for doxygen documentation
–enable-doxygen-man generate doxygen manual pages
–enable-doxygen-rtf generate doxygen RTF documentation
–disable-doxygen-xml don’t generate doxygen XML documentation
–enable-doxygen-chm generate doxygen compressed HTML help documentation
–enable-doxygen-chi generate doxygen seperate compressed HTML help index file
–disable-doxygen-html don’t generate doxygen plain HTML documentation
–enable-doxygen-ps generate doxygen PostScript documentation
–enable-doxygen-pdf generate doxygen PDF documentation
–enable-core-docs Enable building of documentation for avahi-core
–disable-manpages Disable building and installation of man pages
–disable-xmltoman Disable rebuilding of man pages with xmltoman
–enable-tests Enable building of tests and examples
–enable-compat-libdns_sd Enable compatibility layer for libdns_sd
–enable-compat-howl Enable compatibility layer for HOWL

開始編譯:

$sudo -s
#build avahi
$./configure --host=arm-linux-gnueabihf \
--prefix=/opt/ARMv7_ti335x/avahi/ \
--with-distro=none \
--sysconfdir=/etc \
--with-xml=expat \
--with-avahi-user="root" \
--with-avahi-group="root" \
--localstatedir=/var \
-enable-libdaemon \
-disable-shared \
-disable-dbus \
-disable-gdbm \
-disable-autoipd \
-disable-qt3 \
-disable-qt4 \
-disable-gtk \
-disable-gtk3 \
-disable-python \
-disable-mono \
-disable-monodoc \
-disable-doxygen-html \
-disable-xmltoman \
-disable-manpages \
CC=arm-linux-gnueabihf-gcc \
CFLAGS="-I/opt/toolchains/ti335x/cortexa8t2hf-vfp-neon-linux-gnueabi/usr/include -I/opt/ARMv7_ti335x/avahi/include -L/opt/ARMv7_ti335x/avahi/lib -I/opt/ARMv7_ti335x/expat-2.2.9/include -I/opt/ARMv7_ti335x/attr/include" \
LDFLAGS="-L/opt/toolchains/ti335x/cortexa8t2hf-vfp-neon-linux-gnueabi/lib  -L/opt/ARMv7_ti335x/expat-2.2.9/lib /opt/ARMv7_ti335x/expat-2.2.9/lib/libexpat.a -L/opt/ARMv7_ti335x/attr/lib -lattr" \
LIBDAEMON_CFLAGS="-I/opt/ARMv7_ti335x/libdaemon/include" \
LIBDAEMON_LIBS="-L/opt/ARMv7_ti335x/libdaemon/lib/ -ldaemon"

# 註 /opt/ARMv7_ti335x/expat-2.2.9/lib/libexpat.a <= 用這個強制編成static 程式

$make
$make install

6.疑難排解

avahi error: ‘O_CLOEXEC’ undeclared

$gedit avahi-daemon/main.c
#define O_CLOEXEC 0 //<==add line
static char *get_machine_id(void) {
    int fd;
    char buf[32];
    fd = open("/etc/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY);
    if (fd == -1 && errno == ENOENT)
        fd = open("/var/lib/dbus/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY);
    if (fd == -1)
        return NULL;
//(略)
}

No package ‘gtk+-3.0’ found

$sudo apt-get install build-essential libgtk-3-dev
$cd /opt/avahi/etc/avahi/services
# write XXX.service (PS:XXX 自訂)
$vim lxi.service

No package ‘glib-2.0’ found

checking for GLIB20... no
configure: error: Package requirements ( glib-2.0 >= 2.4.0 ) were not met:

No package 'glib-2.0' found
$sudo apt-get install libglib2.0-dev

/libcap.so: undefined reference to XXXX

/opt/toolchains/ti335x/cortexa8t2hf-vfp-neon-linux-gnueabi/lib/libcap.so: undefined reference to `removexattr@ATTR_1.0'
/opt/toolchains/ti335x/cortexa8t2hf-vfp-neon-linux-gnueabi/lib/libcap.so: undefined reference to `fremovexattr@ATTR_1.0'
/opt/toolchains/ti335x/cortexa8t2hf-vfp-neon-linux-gnueabi/lib/libcap.so: undefined reference to `getxattr@ATTR_1.0'
/opt/toolchains/ti335x/cortexa8t2hf-vfp-neon-linux-gnueabi/lib/libcap.so: undefined reference to `setxattr@ATTR_1.0'
/opt/toolchains/ti335x/cortexa8t2hf-vfp-neon-linux-gnueabi/lib/libcap.so: undefined reference to `fsetxattr@ATTR_1.0'
/opt/toolchains/ti335x/cortexa8t2hf-vfp-neon-linux-gnueabi/lib/libcap.so: undefined reference to `fgetxattr@ATTR_1.0'

#./configure 時LDFLAGS 補上 -lattr,本文已加上

運行環境底下

必需建置

Folder:

  1. mkdir -p /run/avahi/
  2. mkdir -p /etc/avahi/services/

File

  1. cp /mnt/nfs/avahi-daemon /sbin/avahi-daemon <= 執行檔
  2. vi /etc/avahi/avahi-daemon.conf
# This file is part of avahi.
#
# avahi is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# avahi is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with avahi; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA.

# See avahi-daemon.conf(5) for more information on this configuration
# file!


[server]
#host-name=foo
#domain-name=local
#browse-domains=0pointer.de, zeroconf.org
use-ipv4=yes
use-ipv6=no
#allow-interfaces=eth0
#deny-interfaces=eth1
#check-response-ttl=no
#use-iff-running=no
#enable-dbus=yes
#disallow-other-stacks=no
#allow-point-to-point=no
#cache-entries-max=4096
#clients-max=4096
#objects-per-client-max=1024
#entries-per-entry-group-max=32
ratelimit-interval-usec=1000000
ratelimit-burst=1000

[wide-area]
enable-wide-area=yes

[publish]
#disable-publishing=no
#disable-user-service-publishing=no
#add-service-cookie=no
#publish-addresses=yes
publish-hinfo=no
publish-workstation=no
#publish-domain=yes
#publish-dns-servers=192.168.50.1, 192.168.50.2
#publish-resolv-conf-dns-servers=yes
#publish-aaaa-on-ipv4=yes
#publish-a-on-ipv6=no

[reflector]
#enable-reflector=no
#reflect-ipv=no

[rlimits]
#rlimit-as=
#rlimit-core=0
#rlimit-data=8388608
#rlimit-fsize=0
#rlimit-nofile=768
#rlimit-stack=8388608
#rlimit-nproc=3
  1. vi /etc/avahi/services/lxi.service <=lxi 服務設定檔
<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
        <name replace-wildcards="yes">%h-yuyan123</name>
        <service protocol="ipv4">
                <type>_lxi._tcp</type>
                <port>80</port>
                <txt-record>txtvers=1</txt-record>
                <txt-record>Model=A-1234</txt-record>
                <txt-record>SerialNumber=GWT123456</txt-record>
                <txt-record>FirmwareVersion=V1.0.0.1.</txt-record>
                <txt-record>Manufacturer=GWINSTEK</txt-record>
        </service>
        <service>
                <type>_http._tcp</type>
                <port>80</port>
        </service>
        <service>
                <type>_scpi-raw._tcp</type>
                <port>5025</port>
        </service>
        <service>
                <type>_scpi-telnet._tcp</type>
                <port>5024</port>
        </service>
        <service>
                <type>_vxi-11._tcp</type>
                <port>111</port>
        </service>
        <service>
                <type>_hislip._tcp</type>
                <port>4880</port>
        </service>
</service-group>

簡易測試

在嵌入式系統端開啟服務 (root 帳號為例)

$avahi-daemon

在 PC 端使用 avahi-unitls 測試,Ubuntu 為例

# install
$sudo apt-get install avahi-untils

# test
$avahi-browse -a | grep _lxi._tcp

  目錄