うたカモ技術ブログ

Linux OpenWrt ネットワーク

【第 6 回】 OpenWrt開発入門   自作アプリのパッケージ作成とインストール

post:     update: 

この記事に掲載しているOpenWrtのパッケージ作成方法は執筆時点で最新のOpenWrt22.03に基づいています。 過去もしくは最新版のOpenWrtではこの記事の内容が当てはまらないかもしれません。予めご了承ください。

この記事では、自作アプリのOpenWrt用パッケージを作成する方法について紹介します。

前回記事で開発したパケットキャプチャソフト(以下、duckdump)を題材に、 対象OpenWrtデバイス用のパッケージを作成、インストールしてみます。

今回は例として、Raspberry Pi3B用のパッケージを作成しますが、 ここで紹介するパッケージ作成方法は、どのOpenWrtデバイスに対しても通用するものです。

そのため、(可能であれば)ご自身のOpenWrtデバイス用にパッケージを作成・インストールしてみることをおススメします。 この作業を通して、この記事の内容について一定の理解をして頂ければ幸いです。

また今回、OpenWrtデバイスのRasberry Pi3Bにインストールするduckdumpは以下のシステム・機能構成を持ちます。 これはOpenWrt専用アプリケーションの最小機能構成です。

  1.   UCIコンフィグレーションファイル(/etc/config/duckdump)を環境変数として使用する
  2.   初期化スクリプト/etc/init.d/duckdumpにより、システム起動時にduckdumpを自動起動する
  3.   初期化スクリプト/etc/init.d/duckdumpにより、duckdumpを操作(起動・停止・再起動)可能にする

この記事では、パッケージの作成方法のみを取り上げるのではなく、自作アプリをOpenWrt専用アプリケーションとして動作させるための構成方法についても紹介します。 読者の方には、それも含めて参考にして頂ければと思います。

それでは行ってみましょう。

注意

この記事では、開発用PC上で作成したパッケージをOpenWrtデバイスにダウンロードさせるために、OpenWrtコンソール上でwgetコマンドを使用しています。 しかし、お使いのOpenWrtデバイス環境によっては、wgetコマンド(もしくはcurlコマンド)が使用できない可能性があります。 その場合は、次回記事で紹介するリポジトリ作成を通して、パッケージマネージャーソフト(opkg)経由でパッケージをダウンロードしてください。 ※とは言え、通常のopkgは内部でwgetを使用しています。

目次

  1. 実施環境と補足事項
  2. 自作アプリ(duckdump)のシステム・機能構成
  3. 自作アプリ(duckdump)構成ファイルのダウンロード
  4. パッケージ構成ファイルについて
  5. パッケージ作成手順
  6. パッケージのインストール
  7. パッケージのアンインストール
  8. OpenWrt専用アプリケーションの使い方
  9. おわりに
  10. 参考文献

実施環境と補足事項

この記事は以下の環境で実施した結果を元に作成しています。

#開発用PCの実行環境OS
ubuntu 22.04 LTS 64bit
#OpenWrtデバイス
  名称:Raspberry Pi3 Model B
  CPU:ARM Cortex-A53 (1.2GHz)
  SOC:Broadcom BCM2837
  RAM:1GB
  ストレージ(media):MicroSDカード
#OpenWrt
OpenWrt 22.03

また、記事内で紹介するコンソール表記は次の通りです。

開発用PCのコンソール表記
ユーザー名とカレントディレクトリを色付けして表記します。
user:~/openwrt$ command
OpenWrtのコンソール表記
ユーザー名はroot@OpenWrtです。
root@OpenWrt:~# command

なお、前提環境として、開発用PCからOpenWrtデバイスにSSH接続できる必要があります。予め確認しておきましょう。 ※OpenWrtをデバイスにインストールしていない、もしくはSSH接続の仕方が不明な方は連載記事の第2回第3回を参照してください。

自作アプリ(duckdump)のシステム・機能構成

今回、OpenWrtデバイスにインストールする自作アプリのduckdumpは、OpenWrtアーキテクチャの1つであるUCIシステム を利用し、キャプチャ対象のNIC名をUCIコンフィグレーションファイル(/etc/config/duckdump)で管理します。

加えて、初期化スクリプト(/etc/init.d/duckdump)をOpenWrt専用初期化プロセス(procd)に認識させることで、システム起動時にduckdumpを自動起動するように設定します。

これにより、初期化スクリプトが提供する次のコマンドを実行することでduckdumpを起動(start)・停止(stop)・再起動(restart)できるようにもなります。

root@OpenWrt:~# /etc/init.d/duckdump start
root@OpenWrt:~# /etc/init.d/duckdump stop
root@OpenWrt:~# /etc/init.d/duckdump restart

これはちょうど、第3回記事のネットワーク・Wi-Fi設定の適用で使用したコマンド「/etc/init.d/network restart」 に酷似します。つまり、duckdumpはOpenWrtのネットワーク・Wi-Fi制御用アプリケーション(netifd)と同一の機能構成を部分的に持ちます。

ここの作り方が分かれば、OpenWrt専用アプリケーションの開発に興味を持ってくれる方が出てくると思います。

それでは次節からduckdumpのOpenWrt用パッケージを作成するための準備をはじめ、その構成について詳細に見ていきましょう。

自作アプリ(duckdump)構成ファイルのダウンロード

前回の記事は、duckdumpのプログラムのみに焦点を当てていたため、掲載ソースコード をそのままコピペして作業を進めても支障はありませんでした。

しかし、今回はパッケージ作成のための設定ファイルが複数ありますので、次のようにGitコマンドを使用して、duckdumpが収録されたUtakamoStudyAppsリポジトリをクローンしてください。 ※クローンする場所は、ユーザーホームディレクトリの好きな場所で構いません。リポジトリの配置場所について特段の制約はありません。

kamo@kamo:~$ git clone https://github.com/utakamo/UtakamoStudyApps.git

UtakamoStudyAppsリポジトリは、次に示すディレクトリ構成で各設定ファイルを管理しています。

この中でも特に重要なディレクトリとファイルの説明は以下の通りです。

UtakamoStudyApps/duckdump/files/src
前回記事で紹介したduckdumpのヘッダファイルを含むC言語ソースファイル一式に加え、これらを自動コンパイルするためのMakeファイルが 保存されているディレクトリです。
UtakamoStudyApps/duckdump/files/etc
OpenWrt専用アプリケーションの環境変数として利用されるUCIコンフィグレーションファイル、初期化スクリプトが保存されているディレクトリです。
UtakamoStudyApps/duckdump/Makefile
パッケージを作成するための設定ファイルです。buildrootが読み込み、記述内容に従ってアプリケーションをビルドします。

これらのディレクトリ・ファイル構成はテキトーに考えているのではなく、パッケージが正しく作成されるように 各ファイルを階層化して管理しています。これを基に、buildrootが使用するMakeファイル(UtakamoStudyApps/duckdump/Makefile) に、各ディレクトリのファイルを処理するコードを記載することでパッケージの作成を実現します。

そのため、以後はこのディレクトリとファイル構成に変更を加えてはいけません。
次節では、各ファイルの詳細について説明します。

パッケージ構成ファイルについて

この節では、duckdumpの各パッケージ構成ファイルについて詳細に見ていきます。
ただし、C言語ソースファイルに関しては、前回記事で取り上げていますので省略します。

注意
ここに掲載した各ソースファイルのコードを自身の環境に直接コピペし、次節で紹介するビルド作業に利用してはいけません。 タブ文字やスペース文字が崩れることで、Makeファイルを中心にエラーが発生します。 そのため、これらのソースファイルは前節で紹介したGitHubリポジトリ(UtakamoStudyApps)から入手してください。

# UtakamoStudyApps/duckdump/files/src/makefile
duckdumpのC言語ソースファイルをコンパイルするためのMakeファイルです。
all: duckdump

CC = gcc
CFLAGS = -Wall
LDFLAGS = -lpcap

DEPS = $(wildcard *.h)

SRC = $(wildcard *.c)

OBJ = $(patsubst %.c, %.o, $(SRC))

%.o: %.c $(DEPS)
    $(CC) -c -o $@ $< $(CFLAGS)

datacheck: $(OBJ)
    $(CC) -o $@ $^ $(LDFLAGS)

.PHONY: clean

clean:
    rm -f duckdump *.o

OpenWrt公式ドキュメントのテンプレートを使用していますが、一般的な記載内容です。 主に、実行可能ファイルのduckdumpとオブジェクトファイルのduckdump.oを作成する手続きについて記載しています。
このMakeファイルはOpenWrtのbuildroot経由で実行されます。 buildroot経由で実行されるとき、変数ccとLDFLAGSにはターゲットデバイス用のコンパイラとライブラリが代入されます。
今回は、Raspberry Pi3Bをターゲットデバイスに設定していますので、変数CCとLDFLAGSにはRaspberry Pi3B搭載チップ対応gccコンパイラとパケットキャプチャライブラリ(libpcap)のライブラリ情報(-lpcap)が渡され、 依存関係を解決した上でコンパイルが開始されます。
※ちなみに、変数CC、LDFLAGSのデフォルト値「gcc」、「-lpcap」は開発用PCの対応コンパイラとライブラリを指します。このMakeファイルのディレクトリがカレントディレクトリのとき、コンソール上で「make datacheck」を実行すれば、開発用PCで 実行可能なduckdumpがコンパイルされます(このときの実行可能ファイル名はdatacheckです)。
# UtakamoStudyApps/duckdump/Makefile
恐らく、パッケージ作成で一番重要なMakeファイルです。
include $(TOPDIR)/rules.mk

PKG_NAME:=duckdump
PKG_VERSION:=1.0
PKG_RELEASE:=1

SOURCE_DIR:=./files/src
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)$(PKG_VERSION)-$(PKG_RELEASE)
#Default PKG_BUILD_DIR
#PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)

DEPENDS:=+libpcap
TARGET_LDFLAGS+=-lpcap

include $(INCLUDE_DIR)/package.mk

define Package/duckdump
    CATEGORY:=utakamo
    SECTION:=utakamo
    TITLE:=utakamo packet capture
endef

define Package/duckdump/description
    ipv4 packet capture
endef

#copy src file from duckdump_dir to build_dir 
define Build/Prepare
    mkdir -p $(PKG_BUILD_DIR)
    cp $(SOURCE_DIR)/* $(PKG_BUILD_DIR)
endef

define Build/Compile
    $(MAKE) -C $(PKG_BUILD_DIR) \
        CC="$(TARGET_CC)" \
        CFLAGS="$(TARGET_CFLAGS)" \
        LDFLAGS="$(TARGET_LDFLAGS)" 
endef

define Package/duckdump/install
    $(INSTALL_DIR) $(1)/etc/init.d
    $(INSTALL_BIN) ./files/etc/init.d/duckdump.init $(1)/etc/init.d/duckdump	
    $(INSTALL_DIR) $(1)/etc/config
    $(INSTALL_CONF) ./files/etc/config/duckdump.config $(1)/etc/config/duckdump
    $(INSTALL_DIR) $(1)/usr/bin
    $(INSTALL_BIN) $(PKG_BUILD_DIR)/duckdump $(1)/usr/bin/duckdump
endef

$(eval $(call BuildPackage,duckdump))    
ターゲットデバイス用パッケージを作成する手続きを記載しています。この中でも特に重要な記述箇所を4つ上げ、その詳細について説明します。 ※なお、こちらもOpenWrt公式ドキュメントのテンプレートを利用しています。興味があれば参照してみてください。
①define Package/duckdump
パッケージのタイトル(TITLE)やカテゴリ情報(CATEGORY)、セクション情報(SECTION)を設定する箇所です。この情報を基に、buildrootはパッケージ情報をコンフィグ画面に表示します。 次はdefine Package/duckdumpの記載情報を基に、コンフィグ画面を表示させた例になります。
②define Build/Prepare
パッケージビルドの前準備としてOpenWrtのビルドシステムであるbuildrootの作業領域(build_dir)に、コンパイル対象のCソースファイル一式をコピーする処理です。
今回は、~/UtakamoStudyApps/duckdump/files/srcのソースファイル(duckdump.c、ducmdump.h、makefile)をbuild_dirの孫ディレクトリ(~/build_dir/aarch64_cortex-a53_musl/duckdump1.0-1)にコピーしています。
このとき、build_dirの子ディレクトリの名前は、ターゲットデバイスの「プロセッサ名+組み込み用C言語標準ライブラリ名」です。 今回の場合は、aarch64_cortex-a53_muslがbuild_dirの子ディレクトリになります。このディレクトリはbuildrootのターゲットデバイス設定を基に、システム内部で自動生成されます。 ターゲットデバイス設定は次節または第2回記事を参照してください。※子ディレクトリまでのパスは、$(BUILD_DIR)で管理されます。
孫ディレクトリは$(PKG_BUILD_DIR)で指定したものです。
今回は、「アプリケーション名+バーション番号+リリース番号」で命名したいので、「$(PKG_NAME)$(PKG_VERSION)-$(PKG_RELEASE)」と しています。これでbuild_dirの孫ディレクトリはduckdump1.0-1になります。
③define Build/Compile
上記によって、build_dirの孫ディレクトリ$(PKG_BUILD_DIR)にコピーされたソースファイルをmakefileでターゲットデバイス用にコンパイルする処理です。 makefileの変数(CC、LDFLAGS)にコンパイラやライブラリ情報を渡してコンパイル・ビルドを実行します。
今回の場合では実行後、同階層に実行可能ファイルのduckdumpとオブジェクトファイルのduckdump.oが作成されます。
この時に使用されるgccコンパイラなどはターゲットデバイスのプロセッサに対応したものです。
ターゲットデバイス設定に紐づくtoolchainに、gccコンパイラや組み込み用C言語標準ライブラリ一式が同梱されますので、 それを使用しています。
④define Package/duckdump/install
ビルドした実行可能ファイルと関連ファイルをパッケージ環境にコピーする処理です。
installコマンドのマクロを使用して、各ファイルに適切な権限を付与した上で、パッケージ環境を表すディレクトリの$(1)にコピーします。 次にinstallコマンドのマクロを掲載します。
マクロ対象コマンド説明
INSTALL_DIRinstall -d -m0755アクセス権限0755でディレクトリを作成
INSTALL_BINinstall -m0755アクセス権限0755で指定ファイルを作成
INSTALL_DATAinstall -m0644アクセス権限0644で指定ファイルを作成
INSTALL_CONF install -m0600アクセス権限0600で指定ファイルを作成
コピー先の$(1)は、build_dirのターゲットデバイス用作業領域直下の「ipkg+プロセッサ名」で命名される ディレクトリです。今回の場合では「ipkg-aarch64_cortex-a53」になります。※このディレクトリもターゲットデバイス設定に基づき、buildrootによって自動生成されます。
今回はipkg-aarch64_cortex-a53ディレクトリに実行可能ファイルのduckudump、UCIコンフィグレーションファイル、 初期化スクリプトをコピーしています。このとき、ipkg-aarch64_cortex-a53直下のディレクトリ構成は各ファイルが インストールされるOpenWrtデバイスのディレクトリ構成に合わせる必要があります。
そのため、$(1)配下のディレクトリ・ファイル構成は次のようになります。
対象ソース$(1)配下のディレクトリ・ファイル構成
duckdump(実行可能バイナリ)$1(1)/usr/bin/duckdump
UCIコンフィグレーションファイル$1(1)/etc/config/duckdump
初期化スクリプト$1(1)/etc/init.d/duckdump
OpenWrtデバイスに合わせ、パッケージ環境内のディレクトリを構成することで、 パッケージインストール時にOpenWrtデバイスの該当箇所に各ファイルがコピーされます。
このディレクトリには、パッケージマネジャーソフト(opkg)がパッケージ情報を認識するためのファイルも格納されます。 これらはbuildrootによって自動で同梱されるものです。
このように、このMakeファイルには実に多くのパッケージ作成処理が記述されます。 buildrootのターゲットデバイス設定を基に、自動生成されるディレクトリも利用してパッケージを作成します。
そのため、初見だと読み解くのが かなり難しいと思います。自作のアプリケーションをパッケージ化する際は、この部分の説明を都度参照して頂ければと思います。
※次節では、第2回記事で紹介したbuildrootのターゲットデバイス設定を再度説明しますので、まだ設定をしていない方はご参考ください。
# UtakamoStudyApps/duckdump/files/etc/config/duckdump.config
duckdumpが使用するUCIコンフィグレーションファイルです。
# duckdump configuration
config duckdump target
    option nic	wlan0
今回は、パケットキャプチャ対象のNIC名をtargetセクションのnicオプションで管理します。 duckdumpは起動時に、このNIC(デフォルトでwlan0)を対象にパケットキャプチャを開始します。
そのため、ご自身のOpenWrtデバイスのNICをifconfigコマンド(または、ip a)で確認して、このファイルに記載されているデフォルト設定のNIC(wlan0)が存在しなければ、 代わりに認識されているNICをここに書いてください。
※なお、UCIコンフィグレーションファイルに関する詳しい説明は以下の記事を参照してください。
【第3回】 OpenWrt開発入門 UCIコマンドによるネットワーク・Wi-Fi設定
OpenWrt UCIコマンドの使い方
# UtakamoStudyApps/duckdump/files/etc/init.d/duckdump.init
duckdumpの初期化&操作スクリプトです。
#!/bin/sh /etc/rc.common

START=99

target=$(uci -q get duckdump.target.nic)

start() {
    /usr/bin/duckdump $target
    
    if [ $? -eq 0 ];then
        echo "duckdump start [target: ${target}]"
    else
        echo 'duckdump error'
    fi
}

stop() {
    killall /usr/bin/duckdump
    echo 'duckdump stop'
}

restart() {
    stop > /dev/null
    sleep 1
    start > /dev/null
    echo 'duckdump restart'
}
先頭行の#!/bin/sh /etc/rc.commonでは、初期化スクリプトの共通処理を実行しています。 rc.commonには、OpenWrtの初期化プロセス(procd)がシステム起動時・終了時・再起動時に使用するstart、stop、restart関数などを呼び出すラッパー処理について記述されています。
そのため、rc.commonを利用した初期化スクリプトは、これらの関数(start, stop, restart, etc...)の具体的な処理を記述する必要があります。
今回は、duckdumpを起動・停止・再起動できるように、スクリプトを記述しています。
start関数に着目すると、専用UCIコンフィグレーションファイル(/etc/config/duckdump)が持つターゲットNIC情報(duckdump.target.nic='wlan0')を取得し、それを引数にduckdumpを起動するように記述しています。
※単純なstopとrestart関数については説明を省略します。
なお、初期化スクリプト内の「START=99」は、procdがそのスクリプトをシステム起動時に、何番目の優先順位(※)で呼び出すかを示すものです。 この記述部分は非常に重要です。OpenWrtデバイスにパッケージをインストールする際に、初期化スクリプトのSTART部分をシステムが認識します。そして、これを基に procdが管理するアプリケーションの起動ディレクトリ/etc/rc.dにその初期化スクリプトのシンボリックリンクが自動生成されます。
※STARTで指定する番号は他アプリケーションと重複した番号でも構いません。
このときのシンボリックリンクの命名規則は、STARTの頭文字「S」をプレフィックスにした「 S+番号+初期化スクリプト名 」です。 そのため、今回の初期化スクリプトduckdumpのシンボリックリンク名は「S99duckdump」になります。
これによって、システム起動時に優先順位99番でduckdumpの初期化スクリプトのstart関数が実行されます。
補足
シャットダウン時にスクリプトを呼び出したい場合は、STOP=99などのように記述します。 これによって終了用のシンボリックリンク「K99duckdump」が/etc/rc.dに作成されます。優先順位99番でduckdumpの初期化スクリプトのstop関数が実行されます。ちなみに、プレフィックス「K」はKillの頭文字です。

それでは、次節からパッケージを作成していきましょう。

パッケージ作成手順

[手順1]:OpenWrt SDKの導入とターゲットデバイス設定
この連載記事の第2回を読んでその内容を既に実施している方は、ここはスキップして下さい。

ここでは、Raspberry Pi3B用のパッケージ作成を紹介します。
そのため、まずは開発用PCにOpenWrt SDKをダウンロードしてください。 ダウンロードされたOpenWrt SDKが管理するbuildrootに対し、ターゲットデバイスとしてRaspberry Pi3Bを指定します。

この内容は第2回で取り上げていますので、次に示すリンク先を順番に読んで実施してください。

  1. OpenWrt SDKのダウンロード
  2. buildrootの使用準備
  3. ファームウェアイメージの作成

※少し冗長ですが、今回は上記リンクを参考にファームウェアイメージの作成まで実施してください。buildrootはファームウェアイメージを作成する際に 必要なツールなどをリポジトリからダウンロードします。そして、依存関係を解決した上でターゲットデバイス用ファームウェアイメージをビルドします。そのため、インストールしないとは言え、ファームウェアイメージを 一度作って全ての依存関係を解決していた方が後々トラブルが発生しづらくなります。

[手順2]:作成対象パッケージのダウンロード
次のGitコマンドでUtakamoStudyAppsリポジトリをクローンしてください。

kamo@kamo:~$ git clone https://github.com/utakamo/UtakamoStudyApps.git

[手順3]:自作アプリのフィード適用とコンパイル
ここではbuildrootに対して自作アプリのフィード(パッケージ情報のまとまり)を適用する方法について説明します。

はじめに、開発用PCにダウンロードしたOpenWrt SDKのディレクトリ(以下、OpenWrtディレクトリ)直下にfeeds.confという 名前のファイルを作成してください。そして、そのファイル中に「src-link」から始まる行(フィード名とパッケージパス)を次のように記載します。

kamo@kamo:~/openwrt$ touch feeds.conf 
kamo@kamo:~/openwrt$ nano feeds.conf
# feeds.confの記載例
# パッケージパスはご自身の環境を確認の上、記述してください
# src-link [フィード名] [パッケージパス]
src-link utakamo /home/kamo/UtakamoStudyApps

フィード名は、buildrootが対象フィード情報を認識するための名前です。
注意したいのは、フィード名とパッケージ名は重複していけません。今回の場合、作成対象のパッケージ名はduckdumpなので、 duckdumpとは異なる名前のutakamoをフィード名に指定しています。

パッケージパスとは、buildrootが読み込むMakefileのディレクトリパスです。
親ディレクトリを指定すると、そのディレクトリを基点にその直下を探索、Makeファイルを読み込みます。

今回、私の環境ではUtakamoStudyAppsリポジトリを/home/kamo直下にダウンロードしましたので、buildrootが利用するMakeファイルを管理する 親ディレクトリパス「/home/kamo/UtakamoStudyApps」を指定しています。

上記の記載が完了したら、次のコマンドでbuildrootのフィードリスト(~/openwrt/feeds/packages)にfeeds.confが示すutakamoフィードを登録します。

kamo@kamo:~/openwrt$ ./scripts/feeds update -a

続けて、次のコマンドでbuildrootにutakamoフィードをインストールします。

kamo@kamo:~/openwrt$ ./scripts/feeds install -a -p utakamo

成功すると、~/openwrt/package/feedsにutakamoフィード情報が作成されます。 これにより、buildrootのコンフィグ画面でduckdumpをインストール対象として指定できます。

実際にコンフィグ画面を表示してみましょう。

kamo@kamo:~/openwrt$ make menuconfig

ここまでの作業が正常に出来ていれば、次のようにutakamo項目が表示されるはずです。 表示されていない場合はfeeds.confのパッケージパスが間違っていることがほとんどです。パスが正しいか確認してください。

そして、このutakamo項目を選択すると、次にduckdumpパッケージの項目が表示されます。

パッケージ項目の確認が済みましたら、duckdump項目にはチェックを入れずにそのままコンフィグ画面を閉じてください。

コンフィグ画面が終了してコンソールに操作が戻りましたら、次のコマンドでbuildrootに作業領域のbuild_dirを準備させます。 ※一度ファームウェアイメージを作成していれば、この処理はすぐに完了します。

kamo@kamo:~/openwrt$ make V=s

これでパッケージ作成に関わる問題は解消されているはずです。
再度、buildrootのコンフィグ画面を表示させ、今度はduckdumpパッケージにチェックを入れて閉じましょう。

次のコマンドでduckdumpパッケージを作成します。

kamo@kamo:~/openwrt$ make package/duckdump/compile

※2回目以降のパッケージ作成はなるべく上記コマンドでなく、「$ make package/duckdump/{clean,compile}」を使いましょう。

成功すれば、次のようなコンソール結果が表示されます。

これにより、~/openwrt/bin/packages直下のディレクトリにduckdumpパッケージが作成されます。
今回の場合は、~/openwrt/bin/packages/aarch64_cortex-a53/utakamoにduckdumpパッケージのduckdump_1.0-1_aarch64_cortex-a53.ipkが作成されます。

パッケージ作成は以上です。
次節では、このduckdumpパッケージをOpenWrtデバイスにダウンロード&インストールする方法について紹介します。

パッケージのインストール

ここでは、前節で作成したduckdumpパッケージをOpenWrtデバイス上にダウンロードし、パッケージマネージャーソフト(opkg)を使用してインストールする方法について説明します。

はじめに、開発用PC上に存在するduckdumpパッケージ(duckdump_1.0-1_aarch64_cortex-a53.ipk)を 今回のターゲットデバイスであるRaspberry Pi3B上にダウンロードします。

手順はまず、開発用PCのduckdumpパッケージが格納されているディレクトリをドキュメントルートとする簡易WebサーバーをPython3で構築します。

duckdumpパッケージが格納されているディレクトリに移動して、次のコマンドを実行してください。このコマンドは、カレントディレクトリをドキュメントルートとする 簡易Webサーバーを80番ポートで立てる処理です。

kamo@kamo:~/openwrt/bin/packages/aarch64_cortex-a53/utakamo$ sudo python3 -m http.server 80

そして次に、開発用PCのIPアドレスとduckdumpパッケージ名から構成されるフルパスを引数に、wgetコマンドをOpenWrtデバイス側で実行します。 今回、私の場合は開発用PCのIPアドレスが192.168.4.203/24でしたので、以下のようにwgetコマンドを実行します。

root@OpenWrt:~# wget http://192.168.4.203/duckdump_1.0-1_aarch64_cortex-a53.ipk

念のため、一連のコマンドを動作させた例を掲載します。
左の開発用PC側コンソールで簡易Webサーバーを動作させつつ、右のOpenWrtデバイス側コンソールでWebサーバー内のduckdumpパッケージをダウンロードします。

補足
お使いのOpenWrtデバイスによっては、wgetコマンド(もしくはcurlコマンド)が使用できない可能性があります。
その場合は、次回記事で紹介するリポジトリ作成を通して、opkg経由からパッケージをダウンロード&インストールしましょう。

パッケージのダウンロードができましたら、後はopkgのinstallコマンドでduckdumpパッケージをインストールします。

root@OpenWrt:~# opkg install duckdump_1.0-1_aarch64_cortex-a53.ipk

インストールが成功すると、UCIコンフィグレーションファイル(/etc/config/duckdump)によって、引数:wlan0でduckdumpが自動起動します。

youtubeでも表示させ、トラフィックを発生させた後に/tmp/duckdump/cap.logを見ると、wlan0上に流れたIPv4通信の キャプチャログを見ることができます。これで自作アプリduckdumpのインストールは完了です。

なお、duckdumpの初期化スクリプト(/etc/init.d/duckdump)はOpenWrtの初期化プロセス(procd)によって認識されます。 そのため、procdが管理する/etc/rc.dを見ると、S99duckdumpの名前でシンボリックリンクが作成されていることが確認できます。

これで、OpenWrtシステムは起動時に優先順位99番でduckdumpのstart関数を実行するようになります。

以上により、この記事のテーマである自作アプリのパッケージ作成とインストールは全て完了です。

パッケージのアンインストール

OpenWrtデバイスにインストールしたアプリケーションをアンインストールするには次のコマンドを実行して下さい。

root@OpenWrt:~# opkg remove duckdump

アンインストール時には初期化スクリプトのstop関数が自動実行されますので、duckdumpはパケットキャプチャを停止します。

OpenWrt専用アプリケーションの使い方

この記事の冒頭で説明したように、初期化スクリプト(/etc/init.d/duckdump)は操作スクリプトでもあります。 そのため、次のコマンドを使用すると対応した処理が実行できます。

※これは一般的なOpenWrt専用アプリケーションの使用方法と考えて下さい。

[アプリケーションの起動]
startコマンドを実行することで、duckdumpを起動します。

root@OpenWrt:~# /etc/init.d/duckdump start

[アプリケーションの停止]
stopコマンドを実行することで、duckdumpを停止します。

root@OpenWrt:~# /etc/init.d/duckdump stop

[アプリケーションの再起動]
restartコマンドを実行することで、duckdumpを再起動します。
この場合、UCIコンフィグレーションファイル(/etc/config/duckdump)のnicオプションを変更した上で、再起動するケースが考えられます。

root@OpenWrt:~# uci set duckdump.target.nic=eth0
root@OpenWrt:~# /etc/init.d/duckdump restart

[番外][アプリケーションのリロード]
今回開発したduckdumpがサポートしないコマンド(reload)です。
リロードを実現するには、プロセス間通信システム(ubus)と連携する実装がduckdumpに必要です。

リロード機能に対応していれば、duckdumpはプロセスを終了せずにUCIコンフィグレーションファイルを動的に取得・適用することができます。 ※現在のduckdumpはrestartコマンドで、プロセスを再起動することによってUCIコンフィグレーションファイルを読み込み直しています。

OpenWrtのプロセス間通信システムであるubusについては、【第 1 回】 OpenWrt開発入門 イントロダクション-ubusを参照して下さい。

このように、OpenWrt専用アプリケーションは対応する/etc/init.d直下のスクリプト経由で操作が可能です。 しかし、reloadコマンドのように、使用するには他サービスと連携するための実装が必要な場合もあります。

おわりに

今回は自作アプリのパッケージ作成方法とインストールについて紹介しました。

理解することが多いので、慣れないうちはエラーが頻発すると思います。困ったらこの記事を都度参照してみてください。

なお、今回お試しで用意したMakeファイルなどのパッケージ作成ソースは、開発者がローカル環境内で管理している ソースコードをOpenWrtのbuildrootに適用させてパッケージとしてコンパイルする記述内容です。

本来、他の開発者やOpenWrtユーザーが容易にコンパイルできる形でソースコードを配布する場合は、buildrootがGitリポジトリから パッケージを直接ダウンロードし、その中のソースコードをコンパイルするのが一般的です。なので、Gitリポジトリと直接連携 させるパッケージMakeファイルの書き方やfeeds.confへの適用方法などを紹介した記事をどこかで書きたいと思います。

次回は、パッケージをローカルリポジトリ経由でOpenWrtデバイスにダウンロード・インストールする方法について紹介します。 パッケージのアップグレード方法についても紹介したいと思いますのでよろしくお願いします。

参考文献