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:
- mkdir -p /run/avahi/
- mkdir -p /etc/avahi/services/
File
- cp /mnt/nfs/avahi-daemon /sbin/avahi-daemon <= 執行檔
- 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
- 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