openwrt學習


【概述】2017.05.15
openWrt是實現智能路由器功能的最成功的開源系統。主要在於3個方面:領導者、基礎設施、實現軟件的技術。
openWrt是linux的發行版。
openWrt是嵌入式設備上運行的linux系統。
openWrt 的文件系統是可寫的,開發者無需在每一次修改后重新編譯,令它更像一個小型的 Linux 電腦系統,也加快了開發速度。
openWrt社區采用6大基礎設施工具支撐整個社區的運轉:
    1.代碼管理工具git。可以跟蹤文件和目錄的歷史信息;
    2.郵件列表。代碼審查及代碼提交集成的地方;
    3.自動構建工具buildbot。編譯機器人,支持持續集成和自動化測試,以及應用程序的自動化部署和軟件開發的管理;
    4.文檔管理工具WiKi。可以讓任何參與人員非常方便地進行編輯、訪問和搜索;
    5.Trac。集成WiKi和問題跟蹤管理系統的項目管理平台;
    6.技術論壇。技術討論平台。

openWrt英文官網:https://openwrt.org/  中文官網:http://www.openwrt.org.cn/
openWrt技術上的成功秘訣在於:
    1.統一編譯框架;
    2.統一配置接口(uci);
    3.開放的軟件包管理系統及讀寫分區系統;
    4.系統總線(ubus);
    5.進程管理模塊(proc);

openWrt特點:
    1.代碼里不含第三方開源寶,只包含開源包地址連接;
    2.編譯時自動下載源代碼、打補丁來滿足指定平台要求,並編譯,還可以修改Makefile來下載最新的軟件包;
    3.使用LuCI作為最終用戶管理界面。LuCI是以Apache許可協議發布的web管理功能代碼;
    4.UCI通用配置管理方法;
    5.通過腳本來調用iptables來實現防火牆功能,配置保存在UCI文件中;
    6.開放和可擴展的OPKG格式安裝升級包。

路由器的整體架構:管理平面、控制平面、數據轉發平面。
openWrt是一個基於Linux的智能路由器操作系統,默認內置了一些基礎功能,主要功能為3部分:網絡功能、系統管理功能、狀態監控功能。

【開發環境及編譯分析】
編譯環境:VMware虛擬機、ubuntu系統
安裝詳細步驟:http://blog.csdn.net/u013142781/article/details/50529030
安裝相關工具和庫:
    (1) 安裝 SVN 工具,用於下載 openwrt 源碼:
    $:'  sudo apt-get install subversion
    (2) 安裝 git 工具
    $:'  sudo apt-get install git-core
    (3) 安裝依賴的庫文件
    $:'  sudo apt-get install gcc g++ binutils patch bzip2 flex bison make autoconf gettext texinfo unzip sharutils ncurses-term zlib1g-dev libncurses5-dev gawk
下載openwrt源碼:
    $:'  mkdir openwrt
    $:'  cd openwrt/
    $:'  git clone git://git.openwrt.org/openwrt.git
下載完 openwrt 的源碼后,為了使 openwrt 支持更多的軟件,需要更新和安裝其他源上面的軟件:
    $:'  ./scripts/feeds update -a
    $:'  ./scripts/feeds install -a
編譯前的配置:
    $:'  make menuconfig
    根據CPU和路由器進行配置,配置后生成默認的編譯配置文件 .config。
編譯:
    $:'  make V=s -j4
    大概 4、5 個小時編譯就會完成,V=s可以顯示詳細的編譯過程和出錯信息,-j4通過4個線程來編譯,會快一些,然后在源碼目錄 bin 下面生成鏡像。
    openwrt-ramips-rt305x-mpr-a2-squashfs-sysupgrade.bin 這個就是我們要的鏡像。

>> 單獨編譯一個模塊,以TcpDump為例:
$:' make package/tcpdump/clean // 清除編譯生成的文件
$:' make package/tcpdump/prepare // 編譯准備,下載、解壓縮、打補丁
$:' make package/tcpdump/configure // 根據設置選項配置生成Makefile
$:' make package/tcpdump/compile // 根據Makefile進行編譯
$:' make package/tcpdump/install // 生成安裝包

openWrt頂層目錄含義:
config/ // 編譯選項配置文件
docs/ // 文檔目錄
include/ // 包含准備環境腳本、下載腳本、編譯Makefile以及編譯指令
package/ // 各種功能的安裝包
scripts/ // 包含准備環境腳本、下載腳本、編譯Makefile以及編譯指令
target/ // 嵌入式平台
toolchain/ // 編譯器和C庫等
tools/ // 通用命令,用來生成固件的輔助工具

在openWrt固件中,幾乎所有的東西都是軟件包(package),可以編譯為 .ipk 結尾的安裝包,這樣就可以很方便的安裝、升級和卸載。
openWrt編譯生成目錄含義:
dl/ // 編譯時下載軟件代碼包臨時目錄
feeds/ // 擴展軟件包目錄
bin/ // 編譯完成后的最終成果目錄
build_dir/ // 編譯中間文件目錄
staging_dir/ // 編譯安裝目錄
log/ // 如果打開了log選項,則編譯log保存在該目錄下

openWrt典型編譯腳本功能:
scripts/download.pl // 下載編譯軟件包源代碼
scripts/patch-kernel.sh // 打補丁腳本
scripts/feeds // 收集擴展包的工具(該命令在編譯前需要執行)
scripts/diffconfig.sh // 收集和默認配置不同之處的工具
scripts/kconfig.pl // 處理內核的配置
scripts/deptest.sh // 自動軟件包依賴項檢查
scripts/metadata.pl // 檢查metadata
scripts/rstrp.sh // 丟棄目標文件中的符號
scripts/timestamp.pl // 生成文件的時間戳
scripts/ipkg-make-index.sh // 生成軟件包的ipkg索引
scripts/ext-toolchain.sh // 工具鏈
scripts/strip-kmod.sh // 刪除內核模塊的符號信息,使文件變小

feeds腳本功能擴展:
通過feeds安裝軟件包后,在后面執行 make menuconfig 命令時,才可以對相關軟件包選擇是否編譯。
例如安裝 luci-app-firewall 軟件包的命令為:./scripts/feeds install luci-app-firewall

【openWrt包管理系統】
軟件包管理:
    $:' opkg update
    // 更新可以安裝的軟件包列表
    $:' opkg install
    // 安裝軟件包,需要第三個參數傳遞一個軟件包的名稱。如 opkg install file
    $:' opkg remove
    // 卸載安裝包,需要第三個參數傳遞一個軟件包的名稱。autoremove可以將不需要的安裝包也刪除。如 opkg remove file --autoremove
    $:' opkg upgrade
    // 升級軟件包,需要第三個參數傳遞一個軟件包的名稱。一般只用來升級應用(非內核軟件)。
查詢信息:
    $:' opkg list
    // 列出所有可使用的軟件包
    $:' opkg list-installed
    // 列出系統中已經安裝的軟件包
    $:' opkg list-changed-conffiles
    // 列出用戶修改過的配置文件
    $:' opkg files <pkg>
    // 列出屬於這個軟件包中的所有文件
    $:' opkg search <file>
    // 列出提供file的軟件包,需要傳遞文件的絕對路徑
    $:' opkg find <regexp>
    // 列出軟件包名稱和regexp匹配的軟件包
    $:' opkg info [pkg]
    // 顯示已安裝pkg軟件包的信息
    $:' opkg download <pkg>
    // 將軟件包pkg下載到當前目錄
    $:' opkg print-architecture
    // 列出安裝包的架構
    $:' opkg whardepends [-A] [pkg]
    // 針對已安裝的軟件包,輸出依賴這個軟件包的軟件包

opkg命令選項:
-A    查詢所有軟件包
-d <dest_name>  使用dest_name作為軟件包安裝的根目錄
-f <conf_file>  使用conf_file作為opkg的配置文件
--nodeps  不按照依賴來安裝,只安裝軟件包自己
--autoremove  卸載軟件包時自動卸載不再使用的軟件包
--force-reinstall  強制重新安裝軟件包


【openWrt系統配置】2017.05.16
MVC(Model-View-Control)模式是經典的Web開發編程模式。
openWrt也是采用該設計模式,模型層采用統一配置接口UCI(Unified Configuration Interface)。

>>UCI簡介
配置文件由配置節(section)組成,語法如下:
config <type> ["<name>"] #section
option <name> "<value>" #option

錯誤的UCI文件語法:
option 'example" "value' (引號沒有配對)
option example some value with space  (帶有空格的值缺少引號)

>>統一配置原理
openWrt系統的核心配置文件,都位於/etc/config/ 目錄下。
例如修改網絡ip:
    $:' uci set network.lan.ipaddr=192.168.6.1
    $:' uci commit network
    通過運行以下命令修改生效:
    $:' /etc/init.d/network restart

常用功能配置文件含義:
/etc/config/dhcp // dnsmasq軟件包配置,包含dhcp和dns設置
/etc/config/dropbear // SSH服務器選項
/etc/config/firewall // 防火牆設置,包含網絡地址轉換、包過濾、端口轉發等
/etc/config/network // 網絡配置,包含橋接、接口、路由配置
/etc/config/system // 系統配置,包含主機名稱、網絡時間同步等
/etc/config/timeserver // rdate的時間服務列表
/etc/config/luci // 基本的LuCI配置
/etc/config/wireless // 無限設置和wifi網絡定義
/etc/config/uhttpd // web服務器選項配置
/etc/config/upnpd // miniupnpd UPnP服務設置
/etc/config/qos // 網絡服務質量的配置文件定義

UCI命令可以寫入配置文件配置信息,格式如下:
    $:' uci [<options>] <command> [<arguments>]
    $:' uci
    // 直接輸入uci可以查看uci的幫助信息和具體參數

UCI命令含義:
add // 增加指定配置文件類型為 section-type 的匿名區段
add_list // 對已存在的list選項增加字符串
commit // 對給定的配置文件寫入修改
export // 導出一個機器可讀格式的配置
import // 以UCI語法導入配置文件
changes // 列出配置文件分階段修改的內容,即未使用 uci commit 提交的修改
show // 顯示指定的選項、配置節或配置文件
get // 獲取指定區段選項的值
set // 設置指定配置節選項的值
delete // 刪除指定的配置節或選項
rename // 對指定的選項或配置節重命名為指定的名字
revert // 恢復指定的選項,配置節或配置文件

UCI API編程接口Libubox:
Libubox是openWrt的一個必備的基礎庫,包含大小端轉換、鏈表、MD5等實用工具基礎庫,采用Cmake來編譯。
    $:' sudo apt-get install cmake
    // 安裝Cmake工具
    $:' tar -xzf libubox-2015-06-14-dlc66ef1131d14f0ed197b368d03fxxx.tar.gz
    $:' cd libubox-2015-06-14
    $:' cmake -D BUILD_LUA:BOOL=OFF -D BUILD_EXAMPLES:BOOL=OFF.
    $:' make
    $:' sudo make install
    // 頭文件 /usr/local/include/libubox;動態鏈接庫libubox.so和libubox.a在/usr/local/lib/目錄下

進入dl目錄,進行解壓縮和編譯安裝:
    $:' tar -xzf uci-2015-04-09.1.tar.gz
    $:' cd uci-2015-04-09
    $:' cmake -D BUILD_LUA:BOOL=OFF .
    $:' make
    $:' sudo make install
    $:' sudo ldconfig
    $:' gcc test.c -o test -luci
    // 編譯test.c時連接UCI庫

系統內核設置:
sysctl.conf是系統啟動預加載的內核配置文件,通過sysctl命令去讀和設置到系統中。
語法格式:
    # comment
    ; comment
    token = value
    // 以#號和分號開頭的均為注釋行,並且忽略空白航,配置值以 key=value 形式進行設置,例如:
    // 設置打開報文轉發為 net.ipv4.ip_forward=1

sysctl.conf文件位置:package/base-files/files/etc/sysctl.conf
sysctl 是用於修改運行中的內核參數的命令,所有可用的內核參數均在 /proc/sys/ 目錄下。
常用命令舉例:
    $:' /sbin/sysctl -a
    // 顯示所有的內核配置
    $:' /sbin/sysctl -n kernel.hostname
    // 查詢kernel.hostname的值
    $:' /sbin/sysctl -w kernel.hostname="zhangsan"
    // 修改系統主機名稱為zhangsan
    $:' /sbin/sysctl -p /etc/sysctl.conf
    // 加載配置

例如:
查詢是否打開路由轉發:
    $:' cat /proc/sys/net/ipv4/ip_forward
打開路由轉發設置:
    $:' echo "1" > /proc/sys/net/ipv4/ip_forward

系統配置文件信息:
/etc/rc.local // 想要在開機后就執行的命令可以寫入該文件
/etc/profile // 為系統的每個登陸用戶設置環境變量
/etc/shells // openWrt采用的shell是 /bin/ash
/etc/fstab // 各種文件系統的描述信息
/etc/services // 互聯網網絡服務類型列表
/etc/protocols // 協議定義描述文件

【openWrt系統下的軟件開發】
>>編譯構建系統
以dnsmasq軟件為例,會有以下文件和目錄:
    /dnsmasq/Makefile    // Makefile提供下載、編譯、安裝、以及生成OPKG安裝包的功能
    /dnsmasq/files
    /dnsmasq/src

>>Makefile中變量定義
PKG_NAME    // 軟件包名稱
PKG_VERSION // 軟件版本號
...
以具體Makefile文件中的變量做實際查看。

>>軟件包定義
    $:' make menuconfig
    Build/
    Package/

>>構建
    軟件包模塊的編譯步驟:准備、配置、編譯、安裝。

總結:
通常新增一個模塊的主要步驟如下:
    1. 在package下增加一個目錄,例如hello/;
    2. 添加src目錄和files目錄;
    3. src目錄存放模塊源碼;
    4. files存放模塊的配置文件及啟動腳本等;
    5. 在hello/下增加Makefile,在Makefile中增加編譯腳本和安裝腳本。
    6. 編譯;
        $:' make package/hello/build
    7. 生成安裝包;
        $:' make package/hello/install
    或者快速重新進行整個編譯過程:
        $:' make package/hello/{clean,compile,install}
    如果加入平台編譯過程,需要在make menuconfig 時選擇hello模塊,再在隱藏的配置文件.config 中增加一項CONFIG_PACKAGE_hello=y這樣就可以在編譯整個系統時自動編譯軟件模塊。

hello示例:Page89
Makefile示例:Page92

【補丁生成及應用工具】
diff工具:
    diff -up 或 diff -uprN來創建補丁包。
    命令使用舉例:
    $:' diff -up ../src/dhcp.c ../src/dhcp_after.c -up > dhcp.patch
    // 修改前和修改后的文件進行多個文件的補丁包創建

diff工具主要參數如下:
-p --show-c-function // 在每一個更改處顯示C函數
-u -U NUM --unified[=NUM] // 按統一格式輸出,子啊補丁中輸出前后NUM行,默認是3行
-N --new-file // 在補丁文件里包含新的文件內容
-r --recursive // 遞歸比較子目錄,很多文件在不同目錄里修改時使用

patch工具:
    應用補丁命令如下:
    $:' patch -p1 < ../dhcp.patch
    恢復應用前的補丁,使用-R參數來執行,即返回到應用補丁前的代碼的命令:
    $:' patch -R -p1 < ../dhcp.patch

如果補丁文件是gzip和bzip2壓縮的,使用如下命令:
    $:' zcat path/to/dhcp_patch.z.gz | patch -p1
    $:' bzcat path/to/dhcp_patch.z.bz2 | patch -p1

patch工具主要參數如下:
-f // 強制打入補丁,不用詢問
-p1 // 略過一層前導目錄
-E // 打完補丁后,如果文件內容為空,會將其移除
-d // 在指定目錄下執行
-R // 用於刪除補丁
--dry-run // 嘗試打入補丁,輸出打入補丁之后的結果,但不做任何真正修改
--verbose // 告訴patch輸出當前盡可能多的信息


【GDB調試】2017.05.18
GDB是GNU項目開發的針對C/C++的語言代碼調試工具。
GDB主要有4個功能來幫助捕捉發生bug時的狀態:
    1. 啟動應用程序;
    2. 調試斷點點可停住;
    3. 檢查程序中當前的狀態;
    4. 動態改變程序;

啟動程序調試:
在編譯的時候加上 -g 選項即可產生調試信息,通常程序交給客戶的時候會使用 -O 選項來優化,有一些編譯器不能同時處理 -g 和 -O 選項。例如:
    $:' g++ -g hello.c -o hello
    $:' gdb hello

常用GDB命令:
break // 在指定的位置或函數處設置斷點
run // 開始執行調試程序
bt // 查看程序運行棧信息,例如:bt full
continue // 在程序中斷之后繼續執行程序
next // 單步執行,如果是函數則執行完這個函數
step // 單步執行,如果是函數則進入函數內部
set args // 設置啟動參數 set args
print // 輸出表達式或變量值
quit // 退出程序調試
list // 輸出現在執行程序停止位置附近的代碼
help // 輸出GDB命令的幫助信息

環境變量設置:
(gdb)show paths
// 顯示程序的查找路徑列表
(gdb)show environment HOME
// 顯示系統的環境變量
(gdb)set environment varname[=value]
// 設置環境變量
(gdb)unset environment varname
// 取消環境變量設置

設置日志文件:
(gdb)set logging on
// 經屏幕輸出同時輸出到文件中,默認輸出到當前目錄下的 gdb.txt
(gdb)set logging off
// 關閉log
(gdb)set logging file file
// 默認輸出為gdb.txt 此命令可以將當前輸出的log文件名改名
(gdb)set logging overwrite
// overwrite參數可以每次重寫一個全新的文件
(gdb)show logging
// 輸出當前日志的設置

獲取幫助,如:
    $:' help
    $:' help stack

命令總結:
(gdb)run // 啟動調試程序
(gdb)attach // 關聯到正在運行中的進程
(gdb)set args // 設置程序啟動時的參數
(gdb)show args // 顯示啟動參數
(gdb)set environment // 設置環境變量
(gdb)show environment // 如果沒有參數就顯示左右環境變量
(gdb)unset environment // 取消環境變量設置
(gdb)help // 獲取幫助
(gdb)apropos // 搜索命令幫助

指令斷點管理:
break [LOCATION] [thread THREADNUM] [if CONDITION]
LOCATION:可以是代碼行號、函數名、或者一個帶有星號的地址
THREADNUM:是線程號,可以用 info threads 命令來查看線程號
    (gdb)info threads       // 查看線程號
    (gdb)info break         // 顯示斷點信息命令
CONDITION:是一個布爾表達式
tbreak 用於設置一個臨時斷點,當命中這個斷點后將刪除斷點。
clear 或 delete 可以用於刪除斷點。

disable 比斷點刪除更好的辦法,暫時不生效,使用的時候可再次啟用,格式如下:
(gdb)disable [breakpoints] [range...]
// breakpoints 為斷點編號,如果不指定,表示所有斷點都不生效
(gdb)enable [breakpoints] [range...]
// 啟用所指定的斷點。
例如:
(gdb)delete breakpoint 1 // 刪除編號為1的斷點
(gdb)disable breakpoint 1 // 禁止編號為1的斷點
(gdb)enable breakpoint 1 // 允許編號為1的斷點
(gdb)clear 50 // 50為源文件行號,該位置的所有斷點將被清除

觀察點管理:
觀察點,是一個特殊的斷點,如果表達式修改了值程序執行就停止了,表達式可以是變量,也可以是幾個變量的組合,有時也叫數據斷點。
watch // 為表達式設置一個觀察點,一旦表達式值發生變化時,馬上停止執行程序
rwatch // 設置讀觀察點,讀到表達式的值時,程序停止執行
awatch // 設置訪問觀察點,當表達式讀或寫時,將停止執行程序
info watchpoints // 列出當前設置的所有觀察點

捕獲點管理:
使用捕獲點調試某些程序事件,如C++異常、共享庫的加載、系統調用、進程啟動等...
當事件發生時,程序會停止執行。
throw // 一個C++拋出的異常
exec // 當程序執行exec函數創建進程時
syscall // 參數為不火系統調用他們的名字或編號
load // 加載共享庫時
fork // 當程序調用fork創建進程時
tcatch // 設置臨時捕獲點

單步調試:
continue // continue [ignore-count] 從斷點停止的地方恢復程序執行,可縮寫為c,ignore-count表示忽略這個位置斷點的次數
step // 繼續執行程序知道控制到達不同的源碼行,可進入函數,可縮寫為s
next // 單步跟蹤,繼續執行同一函數的下一行代碼,不會進入函數,可縮寫為n
finish // 繼續運行程序直到當前選擇的棧幀返回,並輸出返回值,可縮寫為fin
until // 執行程序直到大於當前已經執行的代碼行,在程序循環時經常會用到,即循環體如果執行過一次,使用until命令將執行循環體完成后的下一行代碼處停止

查看程序運行棧幀信息:
backtrace [full]/[number] // 輸出當前整個函數調用棧的信息,整個棧每個幀一行顯示。
frame // 為選擇和輸出棧幀
up // 選擇和輸出棧幀
down // 不帶參數表示選擇向下一層棧幀
return // 返回到當前棧幀的調用處
info frame // 顯示棧幀的所有信息

查看運行中的源程序信息:
list // 如果沒有參數,默認輸出當前10行代碼或者緊接着上次的代碼。
list - // 輸出當前位置之前的10行代碼

查看運行時數據:
print // 輸出執行程序時的運行數據,可縮寫為p,例如:p num
x // 輸出指定參數的地址信息 - 16進制,例如:x /FMT address
d // 10進制
u // 16進制,無符號整型
o // 8進制
t // 2進制
a // 16進制
c // 字符格式
f // 浮點數格式
$pc // 程序計數器
$fp // 棧指針
$sp // 棧指針
$ps // 處理器狀態

動態改變程序的執行:
print argc=2 // 修改變量的值
set // 修改程序值
jump // 跳轉到指定行或地址來繼續執行
signal // 向程序發信號
call // 調用函數,不輸出函數返回值

【網絡基礎知識】
OSI互聯網協議層分為7層:應用層、表示層、會話層、傳輸層、網絡層、數據鏈路層、物理層
TCP/IP協議層次分為4層:應用層、傳輸層、網絡層、數據鏈路層

網絡設備:
集線器:HUB,在物理層上實現局域網的互聯,可以實現電氣信號的恢復和整型。
網橋:工作在數據鏈路層,網橋負責分析目的MAC地址字段是否在對方網絡上。
路由器:Router,網絡層設備,用於將兩個或多個不同網絡連接在一起。
防火牆:Firewall,是在兩個或多個網絡之間用於設置安全策略的一個或多個系統的組合。

數據鏈路層:
以太網:目前最流行的局域網傳輸標准。
MAC地址:網卡物理地址,長度為6個字節,表示為12個十六進制的數字。例如:08:00:27:26:c5:5d
廣播域:發送到網絡中所有節點的數據分組。網橋和交換機根據MAC地址轉發數據幀,不隔離廣播域。路由器不會轉發廣播報文,為廣播域的邊界。
ARP協議:根據主機的IP地址來查詢其網卡MAC地址,即通過目標IP知道對方的MAC地址。

IP協議:
網絡協議層主要包括兩部分:IP和ICMP。
IP協議是不可靠的、無連接的網絡協議,可靠性需要上層協議來保證。
IP協議報文格式可以百度查看。

IP地址分類:
      ipv4("4個字節的32位地址")
      ipv6 ("16個字節的128位地址")
ip地址包括兩部分內容,"網絡號和主機號"。
 "A類":0~127 . 0~255 . 0~255 . 0~255 以0為首的8位網絡地址+24位本地地址
 0.0.0.0  "主機號全0不能使用 ",主機號全0代表的是網絡號。
 0.255.255.255 "主機號全1不能用 ",這代表的是該網絡的廣播地址。
 127.0.0.0  127.255.255.255
 "B類":128~191 . 0~255 . 0~255 . 0~255 以10為首的16位網絡地址+16位本地
 "C類":192~223 . 0~255 . 0~255 . 0~255 以110為首的24位網絡地址+8位本地
 "D類":以 1110 為首的32位多播地址(28位多播組號)
 "E類":以 11110 為首的32位多播地址(27位留后待用)

子網掩碼:
示例 ip(192.168.129/24, 前面24位全1,即子網掩碼255.255.255.0 )

常見的特殊IP地址塊:
10.0.0.0/8 // A類內部私有地址
172.16.0.0/12 // B類內部私有地址
192.168.0.0/16 // C類內部私有地址
127.0.0.0/8 // 本地回環地址,用於回路測試,不能路由到主機外部
169.254.0.0/16 // 自動配置為成功后分配的ip地址
0.0.0.0/8 // 本地網絡,禁止使用
255.255.255.255 // 受限廣播地址
net.255 // 網絡廣播地址

ICMP協議:
使用IP協議進行傳輸報文,是一種面向無連接的協議,用於報告傳輸出錯及控制,每一個網絡層模塊必須實現該協議。
例如:
ping 命令,實際就是發送ICMP查詢報文,用於查詢網絡連通性。
    通常步驟:先ping本機ip,其次ping網關地址,最后ping目的主機地址
traceroute 命令也是基於ICMP協議的,探測網絡報文經過的路徑。

傳輸層協議:
網絡傳輸協議主要分為傳輸控制協議TCP和用於數據報協議UDP。
路由器一般工作在IP層,不處理傳輸層協議,但智能路由器一般帶有防火牆功能,需要處理端口號。
傳輸數據之前需要進行3次握手連接,並在傳輸的中間過程進行確認,保證了數據到達目標地址,如果沒有到達將立即重傳。

【路由器基礎軟件模塊】
libubox
提供多種基礎通用功能接口,包含鏈表、平衡二叉樹、二進制塊處理、key-value鏈表、MD5等,提供多種sock接口封裝,提供一套基於事件驅動的機制及任務隊列管理功能。
常用uloop接口函數:
uloop_fd_add // 將一個新文件描述符增加到事件處理循環中
uloop_fd_delete // 從事件處理循環中刪除指定的文件描述符
uloop_init // 初始化uloop內部將調用epoll_create函數來創建epoll對象
uloop_run // 進入事件處理循環中
uloop_done // 反初始化uloop,即釋放內部epoll對象,刪除process對象
uloop_end // 設置uloop內部結束循環標志
uloop_timeout_set // 設置定時器超時時間,並增加到鏈表中

jshn
是封裝JSON對象的轉換庫,用於腳本語言生成JSON對象和將JSON對象數據取出。
JSON是一個輕量級的數據交換格式,易於閱讀和編寫,對程序來說也容易解析和產生。
jshn定義的命令接口:
json_init // 初始化JSON對象
json_add_string // 增加字符串數據類型,例如json_add_string name jiang
json_dump // 以JSON格式輸出所有增加的JSON內容
json_add_int // 增加整型數據,例如 json_add_int age 26
json_add_boolean // 增加布爾型數據
json_set_namespace // 定義命名空間,即定義設置變量的前綴
json_load // 將所有內容讀入到JSON對象中,並將這些對象設置到環境變量
json_get_var // 從環境變量中讀取JSON對象的值
json_get_type // 從環境變量讀取指定JSON對象的類型
json_get_keys // 從環境變量中讀取JSON對象的所有名稱
json_get_values // 從環境變量中讀取JSON對象的所有值
json_select // 選擇JSON對象
json_add_object // 增加對象,該命令不需要參數
json_close_object // 完成對象的增加
json_add_array // 增加順序數組,數組的內容后續通過 json_add_string 增加
json_close_array // 完成順序數組的增加
json_cleanup // 清楚jshn所有設置的環境變量

ubus
openWrt提供的一種系統總線,主要提供系統級的進程間通信(IPC)功能。
主要由3部分組成:精靈進程、接口庫、實用工具。
/etc/init.d/ubus中提供ubusd進程的啟動,在系統進程啟動完成后立即啟動,是在網絡進程netifd之前啟動的,該進程監聽一個文件套接字接口和其他應用程序通信。
接口庫名稱為libubus.so
libubus.so庫中常用接口函數含義:
ubus_add_object // 將對象加入到ubus空間中,即客戶端可以訪問對象
ubus_register_subscriber // 增加訂閱通知
ubus_connect // 連接指定的路徑,創建並返回路徑所代表的ubus上下文
ubus_send_reply // 執行完成方法調用后發送相應
ubus_notify // 給對象的所有訂閱者發送通知
ubus_lookup // 查找對象,參數path為對象的路徑,如果為空則查找所有對象
ubus_lookup_id // 查找對象的id
ubus_invoke // 調用對象
ubus_register_event_handler // 注冊事件處理句柄
ubus_send_event // 發送事件消息

ubus命令行工具:
ubus提供5種命令行命令。
ubus list ... -v // 輸出所有注冊到ubus RPC服務器的對象
ubus call ... // 在指定對象里調用指定的方法並傳遞消息參數
ubus listen ... // 設置一個監聽套接字來接收服務器發出的消息
ubus send ... // 發出一個通知事件,這個事件可以使用listen命令監聽到
ubus wait_for ... // 等待多個對象注冊到ubus中,當等待對象注冊成功后退出

netifd
一個管理網絡接口和路由功能的后台進程,使用C語言編寫的帶有RPC能力的精靈進程。
netifd不需要shell腳本就可以設置靜態ip配置。
netifd主要包含設備和接口對象。
netifd注冊了3中對象,分別是network、network.device、network.interface
network對象方法:
restart // 整個進程關閉后重新啟動
reload // 重新讀取配置來初始化網絡設備
add_host_route // 增加靜態主機路由
get_proto_handlers // 獲取系統所支持的協議處理函數,不需要參數

network.device對象方法:
status // 獲取物理網卡設備的狀態,包含統計信息

network.interface對象方法:
up // 啟動接口
down // 關閉接口
status // 查看接口狀態
add_device // 增加設備
remove_device // 刪除設備
notify_proto // 調用原型函數
remove // 刪除接口
set_data // 設置額外的存儲數據

netifd文件:
/sbin/ifup // 啟動接口
/sbin/ifdown // 關閉接口
/sbin/devstatus // 獲取網卡設備狀態
/sbin/ifstatus // 獲取接口的狀態

網絡配置文件:
網絡功能配置信息在文件 /etc/config/network 中。

ifname // 物理網卡接口名稱,如 eth0
type // 網絡類型
proto // static表示靜態配置,dhcp表示動態配置,PPPoE表示點對點撥號連接
ipaddr // ip地址
netmask // 網絡掩碼
dns // 域名服務器地址
mtu // mtu地址

hostname // dhcp請求中的主機名
vendorid // dhcp請求中的廠商id
ipaddr // 建議的ip地址

ifname // PPPoE所使用的物理網卡接口名稱,如 eth0
username // PAP或CHAP認證用戶名
password // PAP/CHAP認證密碼
demand // 指定空閑時間之后將連接關閉,以時間為單位計費環境下經常使用

openWrt無線接口:
#:' iwconfig
無線接口配置文件:/etc/config/wireless
【IP路由】
路由表管理:
#:' route -n
靜態路由配置文件:/etc/config/network

策略路由使用 "ip rule" 來管理,有其對應命令格式。

————————————————
版權聲明:本文為CSDN博主「不才b_d」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/sinat_36184075/article/details/72231970


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM