libnl庫應(yīng)用詳解(一)

??libnl庫提供了一套應(yīng)用于Linux系統(tǒng)基于Netlink協(xié)議通信的API接口。從本質(zhì)上看,Netlink其實(shí)是一種典型的IPC機(jī)制茴迁,只不過此IPC主要是介于用戶空間與內(nèi)核空間之間的通信,而非傳統(tǒng)意義上用戶空間進(jìn)程之間的通信。Netlink是設(shè)計(jì)出來替換ioctl機(jī)制顷编,就目前的使用情況,這一點(diǎn)顯然還沒有完全達(dá)到剑刑。

構(gòu)成

??libnl在設(shè)計(jì)上被分割為若干個(gè)小型庫(small libraries)媳纬,應(yīng)用程序在鏈接時(shí)可以擇庫鏈接,無需將所有庫鏈接到應(yīng)用程序中施掏。

  • libnl:libnl的核心庫钮惠,構(gòu)建Netlink通信的基礎(chǔ),提供套接字操作七芭、消息構(gòu)建/解析素挽、收發(fā)報(bào)文等操作
  • libnl-route:提供NETLINK_ROUTE家族的API接口庫,包括網(wǎng)絡(luò)設(shè)備狸驳、路由功能预明、IP地址、鄰居功能等操作
  • libnl-genl:通用Netlink操作
  • libnl-nf:NetFilter以及接口監(jiān)控相關(guān)的Netlink操作
    libnl庫構(gòu)成及基本特性

使用方法

頭文件

libnl提供的主要頭文件為<netlink/netlink.h>耙箍,此外還提供了一些其他頭文件撰糠,可以視應(yīng)用程序的需要酌情增刪。

#include <netlink/netlink.h>

#include <netlink/cache.h>
#include <netlink/route/link.h>
#include <netlink/route/addr.h>

鏈接

可以在gcc中直接鏈接libnl庫

$ gcc myprogram.c -o myprogram $(pkgconfig --cflags --libs libnl-3.0)
$ #或采取直接鏈接方式
& gcc -Wall -Wextra -pedantic listif.c -o lsif -lnl-3 -lnl-route-3 -isystem /usr/include/libnl3

Netlink協(xié)議

??Netlink 協(xié)議是基于套接字的進(jìn)程間通信(IPC)機(jī)制辩昆,它可用于用戶空間進(jìn)程和內(nèi)核之間或者用戶空間進(jìn)程之間的通信阅酪。Netlink協(xié)議基于BSD套接字并使用AF_NETLINK地址簇。每一個(gè)Netlink協(xié)議都有自己的協(xié)議號(hào)(比如:NETLINK_ROUTE卤材、NETLINK_NETFILTER等)遮斥。它的尋址方案是基于 32 位的端口號(hào)(之前被稱為 PID),此端口號(hào)用于唯一地標(biāo)識(shí)每一個(gè)對(duì)等通信節(jié)點(diǎn)扇丛。

尋址

??Netlink 地址(端口)由一個(gè) 32 位的整數(shù)組成术吗。端口(port)零保留給內(nèi)核使用,表示每個(gè)Netlink協(xié)議簇中內(nèi)核部分的套接字帆精,其他的端口則通常指的是用戶空間的套接字较屿。
??注意: 最初通常使用進(jìn)程標(biāo)識(shí)符(PID)作為本地端口號(hào)隧魄,但這種方式隨著線程化Netlink應(yīng)用程序的引入而失效,因?yàn)檫@類進(jìn)程需要多個(gè)套接字隘蝎。為解決此項(xiàng)沖突购啄,libnl以進(jìn)程標(biāo)識(shí)符為基數(shù)再加上一個(gè)偏移量來生成唯一的端口號(hào),此方式可以讓一個(gè)進(jìn)程使用多個(gè)套接字嘱么。出于向后兼容方面的考慮狮含,第一個(gè)套接字還是以進(jìn)程標(biāo)識(shí)符作為端口號(hào)。

Netlink尋址

??上圖中用戶空間有三個(gè)應(yīng)用程序曼振,對(duì)應(yīng)有5個(gè)套接字几迄;而內(nèi)核空間則創(chuàng)建了2個(gè)套接字。同時(shí)冰评,此圖也展示了Netlink的常見應(yīng)用場景:

  • 用戶空間的進(jìn)程和內(nèi)核的通信
  • 用戶空間內(nèi)進(jìn)程之間的通信
  • 偵聽內(nèi)核的多播通知

應(yīng)用場景

用戶空間進(jìn)程和內(nèi)核的通信

??Netlink最常見的應(yīng)用場景就是用戶空間應(yīng)用程序發(fā)送請(qǐng)求給內(nèi)核映胁,比如設(shè)置/讀取接口的IP地址,然后接受并處理內(nèi)核返回的信息甲雅,這個(gè)回復(fù)信息要么是請(qǐng)求出錯(cuò)的信息解孙,要么就是請(qǐng)求成功的通知信息。


用戶空間和內(nèi)核空間通信

用戶空間進(jìn)程之間的通信

??Netlink也可以直接作為用戶空間應(yīng)用程序之間的進(jìn)程間通信機(jī)制抛人,但這種方式并不常見弛姜,通常會(huì)代之以u(píng)nix域套接字。這種通信并不限制在兩個(gè)對(duì)等通信節(jié)點(diǎn)之間函匕,任意一個(gè)節(jié)點(diǎn)都可以和其他的對(duì)等點(diǎn)進(jìn)行通信娱据。此外因?yàn)镹etlink支持多播,一條消息可以由多個(gè)節(jié)點(diǎn)同時(shí)接收到盅惜。
??注意:為了讓套接字對(duì)通信雙方可見中剩,這兩個(gè)套接字必須在同一個(gè)Netlink協(xié)議簇下創(chuàng)建。


用戶空間之間通信

偵聽內(nèi)核的多播通知信息

??此類Netlink通信是一種非常常見的應(yīng)用方式抒寂,此方式可以讓用戶空間那些需要處理特定內(nèi)核事件的的守護(hù)進(jìn)程偵聽內(nèi)核反饋的消息/事件结啼。這些應(yīng)用程序進(jìn)程通常會(huì)訂閱內(nèi)核使用的某個(gè)多播組,內(nèi)核則在某些事件發(fā)生的時(shí)候通過它來通知訂閱該組播組的進(jìn)程屈芜。


偵聽內(nèi)核多播通知消息

??相對(duì)于直接尋址來說郊愧,多播(組播)尋址是一個(gè)更好的方式,因?yàn)樗懈叩撵`活性井佑,可以在無需通知內(nèi)核的情況下隨時(shí)與用戶空間應(yīng)用組件交換信息属铁。

消息格式

??Netlink協(xié)議通常是基于消息的,消息則通常是由Netlink消息頭部(struct nlmsghdr)加上有效載荷組成躬翁。雖然有效載荷可以由任何數(shù)據(jù)組成焦蘑,但是它通常的格式是一 個(gè)固定大小的協(xié)議相關(guān)頭部后面緊跟一系列的屬性。


Netlink消息頭組成
  • 總長度(32 位):消息包括 netlink 消息頭部在內(nèi)的總字節(jié)數(shù)
  • 消息類型(16 位):消息類型指明了消息的有效載荷的類型盒发。netlink 協(xié)議定義了多個(gè)標(biāo)準(zhǔn)的消息類型例嘱。每個(gè)協(xié) 議簇都可能定義了額外的消息類型狡逢。
  • 消息標(biāo)志(16 位):消息標(biāo)志可以用來更改消息類型的行為。
  • 序列號(hào)(32 位):序列號(hào)的使用是可選的拼卵,它可以用來引用前一條消息奢浑。比如一條錯(cuò)誤消息中可以引用導(dǎo)致錯(cuò) 誤的那條請(qǐng)求消息。
  • 端口號(hào):端口號(hào)指明了這條消息需要發(fā)往哪個(gè)對(duì)等節(jié)點(diǎn)腋腮。如果沒有指定端口號(hào)雀彼,那么這條消息會(huì)被投 遞給同一個(gè)協(xié)議簇中第一個(gè)匹配的內(nèi)核端套接字。

消息類型

??Netlink 在請(qǐng)求消息(requests)低葫、通知消息(notifications)和應(yīng)答消息(replies)的 處理上是有區(qū)別的详羡。請(qǐng)求消息設(shè)有 NLM_F_REQUEST 標(biāo)志位,它用來向接收方請(qǐng)求某種響應(yīng) 嘿悬。一般來說請(qǐng)求消息都是從用戶空間發(fā)送到內(nèi)核的。雖然不是強(qiáng)制規(guī)定水泉,但每次發(fā)送的請(qǐng)求 消息序列號(hào)都應(yīng)該是上一個(gè)序列號(hào)加一善涨。
??由于請(qǐng)求自身的特性,接收方在收到請(qǐng)求消息之后可能會(huì)發(fā)送另一條 netlink 消息來響應(yīng) 這個(gè)請(qǐng)求草则。應(yīng)答消息的序列號(hào)必須和它響應(yīng)的那條請(qǐng)求消息的序列號(hào)一致钢拧。
??通知消息則沒有那么嚴(yán)謹(jǐn),它不需要應(yīng)答炕横,所以序列號(hào)通常是被設(shè)置成 0 的源内。


消息類型

消息的類型主要是由消息頭部中 16 位的消息類型字段確定的。Netlink 定義了如下標(biāo)準(zhǔn)消息類型:

  • NLMSG_NOOP - 無需任何操作份殿,消息必須被丟棄
  • NLMSG_ERROR - 錯(cuò)誤消息或者是 ACK膜钓,
  • NLMSG_DONE - 分段序列的結(jié)束
  • NLMSG_OVERRUN - 通知消息越界錯(cuò)誤

??每個(gè) netlink 協(xié)議都可以自由的定義自己的消息類型。需要注意的是小于 NLMSG_MIN_TYPE(0x10) 的類型是保留的卿嘲,所以不能使用颂斜。通常我們會(huì)定義自己的消息類型來實(shí)現(xiàn) RPC 模式。假設(shè)你的 netlink 協(xié)議的目的是允許你 配置一個(gè)網(wǎng)絡(luò)設(shè)備的某些部分拾枣,所以你想要提供各種配置選項(xiàng)的讀/寫訪問沃疮。完成這項(xiàng)任務(wù) 典型的 “netlik 解決方案” 是定義兩種消息類型MSG_SETCFG,MSG_GETCFG:

#define MSG_SETCFG    0x11
#define MSG_GETCFG    0x12

??發(fā)送一條 MSG_GETCFG 請(qǐng)求消息通常會(huì)收到一條包含當(dāng)前配置信息的類型為 MSG_SETCFG 的應(yīng)答消息梅肤。用面向?qū)ο蟮男g(shù)語來說這叫做“內(nèi)核在用戶空間設(shè)置了配置信息的本地拷貝”


配置信息可以通過發(fā)送一條 MSG_SETCFG 信息來更改司蔬,這條消息會(huì)收到一條 ACK響應(yīng)信息 或是一條錯(cuò)誤信息。

??此外姨蝴,內(nèi)核也可以在配置信息發(fā)生改變的時(shí)候發(fā)送通知信息俊啼,這樣用戶空間應(yīng)用程序就可以 使用監(jiān)聽而不是頻繁輪詢的方式來獲取改變信息。通知消息通常是使用目前已有的消息類型 這就需要應(yīng)用程序使用不同的套接字處理請(qǐng)求消息和通知消息似扔,當(dāng)然你也可以使用特殊的消息類型來單獨(dú)表示通知信息吨些。

分片消息

??理論上一條 netlink 消息的最大長度是 4GiB搓谆,但是套接字的緩沖區(qū)一般不會(huì)設(shè)置有如此大的空間來容納4GiB消息。通常情況下豪墅,消息的長度被限制在頁的大腥帧(PAGE_SIZE )之內(nèi),然后使用分片機(jī)制把大消息分割為多個(gè)消息偶器。分片消息設(shè)有NLM_F_MULTI標(biāo)志位斩萌,接收者需要不斷的接收和解析消息,直至收到一個(gè)消息類型為NLMSG_DONE的消息為止屏轰。
??和分片之后的ip包不一樣颊郎,分片之后的Netlink消息無需重組,但是如果協(xié)議需要重組霎苗,也可以執(zhí)行重組動(dòng)作姆吭。分片消息經(jīng)常會(huì)被用來發(fā)送對(duì)象列表或者是對(duì)象樹,這種情況下消息段只是簡單的承載幾個(gè)對(duì)象唁盏,一般允許單獨(dú)處理每個(gè)消息分片内狸。

分片消息

錯(cuò)誤消息

??錯(cuò)誤消息可以作為請(qǐng)求消息的響應(yīng)發(fā)送回去,錯(cuò)誤消息必須使用標(biāo)準(zhǔn)的消息類型 NLMSG_ERROR厘擂,它的有效載荷是由錯(cuò)誤碼和原來的請(qǐng)求消息頭部組成昆淡。

錯(cuò)誤消息

注意:錯(cuò)誤消息的序列號(hào)必須和導(dǎo)致錯(cuò)誤發(fā)生的請(qǐng)求消息的序列號(hào)設(shè)置為一致。

ACKs消息

??發(fā)送方可以通過設(shè)置NLM_F_ACK標(biāo)志位來要求接收方為處理過的每一個(gè)請(qǐng)求消息都發(fā)送一 個(gè)ACK消息刽严。這種方式通常是用來讓發(fā)送方在請(qǐng)求被接收方處理之后同步下一步的操作昂灵。

ACKs消息

??ACK 消息和錯(cuò)誤消息使用一樣的消息類型(NLMSG_ERROR)和負(fù)荷格式,不同的是 ACK 消息 的錯(cuò)誤代碼被設(shè)置為 0舞萄。

消息標(biāo)志

#define NLM_F_REQUEST           1
#define NLM_F_MULTI             2
#define NLM_F_ACK               4
#define NLM_F_ECHO              8
  • NLM_F_REQUEST - 請(qǐng)求消息
  • NLM_F_MULTI - 分片消息
  • NLM_F_ACK - 請(qǐng)求了 ACK 回復(fù)
  • NLM_F_ECHO - 請(qǐng)求回應(yīng)這個(gè)請(qǐng)求消息眨补。

??NLM_F_ECHO標(biāo)志和NLM_F_ACK標(biāo)志類似,它可以和NLM_F_REQUEST標(biāo)志位一起使 用鹏氧,使得發(fā)送者能夠收到作為這條請(qǐng)求消息的響應(yīng)而產(chǎn)生的通知信息渤涌,無論發(fā)送者是否訂閱過相應(yīng)的多播組。
GET 請(qǐng)求還定義了一些額外的通用標(biāo)志位:

#define NLM_F_ROOT      0x100
#define NLM_F_MATCH     0x200
#define NLM_F_ATOMIC    0x400
#define NLM_F_DUMP      (NLM_F_ROOT|NLM_F_MATCH)
  • NLM_F_ROOT - 返回樹的根節(jié)點(diǎn)把还。
  • NLM_F_MATCH - 返回所有匹配的節(jié)點(diǎn)实蓬。
  • NLM_F_ATOMIC - 已廢棄,以前用來請(qǐng)求一個(gè)原子操作
  • NLM_F_DUMP - 返回一個(gè)含有所有對(duì)象的列表(NLM_F_ROOT|NLM_F_MATCH)

??這些標(biāo)志的使用是完全可選的吊履,許多netlink協(xié)議都只使用NLM_F_DUMP標(biāo)志安皱。這個(gè)標(biāo)志通常用來請(qǐng)求接收者發(fā)送一個(gè)包含所有對(duì)象的列表,而這個(gè)列表則通常是一系列的消息分片艇炎。
??還有一些和 NEW 或者是 SET 請(qǐng)求相關(guān)的標(biāo)志酌伊。這些標(biāo)志和 GET 的那些標(biāo)志是彼此互斥的 :

#define NLM_F_REPLACE   0x100
#define NLM_F_EXCL      0x200
#define NLM_F_CREATE    0x400
#define NLM_F_APPEND    0x800
  • NLM_F_REPLACE - 如果對(duì)象存在的話,替換它。
  • NLM_F_EXCL - 如果這個(gè)對(duì)象存在的話居砖,就不用更新它虹脯。
  • NLM_F_CREATE - 如果對(duì)象不存在的話,創(chuàng)建它奏候。
  • NLM_F_APPEND - 在對(duì)象列表的末尾添加新的對(duì)象循集。

這些標(biāo)志含義在不同的 netlink 協(xié)議中可能會(huì)有細(xì)微的差別。

序列號(hào)

??Netlink允許通過序列號(hào)來關(guān)聯(lián)回復(fù)和請(qǐng)求蔗草。需要注意的是咒彤,這里的序列號(hào)和 TCP 這類的協(xié)議的序列號(hào)是不一樣的,Netlink的序列號(hào)并不強(qiáng)制使用咒精。序列號(hào)唯一的用途就是把一條應(yīng)答消息和相應(yīng)的請(qǐng)求消息聯(lián)系起來镶柱,序列號(hào)是以單個(gè)套接字為基礎(chǔ)來管理。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末模叙,一起剝皮案震驚了整個(gè)濱河市歇拆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌范咨,老刑警劉巖查吊,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異湖蜕,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)宋列,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門昭抒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人炼杖,你說我怎么就攤上這事灭返。” “怎么了坤邪?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵熙含,是天一觀的道長。 經(jīng)常有香客問我艇纺,道長怎静,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任黔衡,我火速辦了婚禮蚓聘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘盟劫。我一直安慰自己夜牡,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布侣签。 她就那樣靜靜地躺著塘装,像睡著了一般急迂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蹦肴,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天僚碎,我揣著相機(jī)與錄音,去河邊找鬼冗尤。 笑死听盖,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的裂七。 我是一名探鬼主播皆看,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼背零!你這毒婦竟也來了腰吟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤徙瓶,失蹤者是張志新(化名)和其女友劉穎毛雇,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體侦镇,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡灵疮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了壳繁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片震捣。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖闹炉,靈堂內(nèi)的尸體忽然破棺而出蒿赢,到底是詐尸還是另有隱情,我是刑警寧澤渣触,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布羡棵,位于F島的核電站,受9級(jí)特大地震影響嗅钻,放射性物質(zhì)發(fā)生泄漏皂冰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一啊犬、第九天 我趴在偏房一處隱蔽的房頂上張望独郎。 院中可真熱鬧覆糟,春花似錦衩婚、人聲如沸咒林。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽峻贮。三九已至席怪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間纤控,已是汗流浹背挂捻。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留船万,地道東北人刻撒。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像耿导,于是被迫代替她去往敵國和親声怔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 操作系統(tǒng)概論 操作系統(tǒng)的概念 操作系統(tǒng)是指控制和管理計(jì)算機(jī)的軟硬件資源舱呻,并合理的組織調(diào)度計(jì)算機(jī)的工作和資源的分配醋火,...
    野狗子嗷嗷嗷閱讀 11,931評(píng)論 3 34
  • 計(jì)算機(jī)系統(tǒng)漫游 代碼從文本到可執(zhí)行文件的過程(c語言示例):預(yù)處理階段,處理 #inlcude 箱吕, #defin...
    willdimagine閱讀 3,586評(píng)論 0 5
  • 多線程芥驳、特別是NSOperation 和 GCD 的內(nèi)部原理。運(yùn)行時(shí)機(jī)制的原理和運(yùn)用場景茬高。SDWebImage的原...
    LZM輪回閱讀 2,007評(píng)論 0 12
  • 誰的故事:木月晴圖片來源:百度 月晴早上開始給小蝴蝶挑選結(jié)婚禮物兆旬,挑來挑去都沒有稱心如意的,十字繡怎栽?加濕器爵憎?藍(lán)牙音...
    笑六子閱讀 179評(píng)論 0 0
  • 沙漠的日落快極了,這片廣袤的黃色土地很快披上一層深色薄紗婚瓜。只有沙丘的最頂端,還能依稀看得到一點(diǎn)點(diǎn)光亮刑棵,剩下...
    張小兵閱讀 602評(píng)論 0 6