日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux网络设备描述符,Linux

發布時間:2023/12/10 linux 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux网络设备描述符,Linux 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載:http://blog.csdn.net/firo_baidu/article/details/6145231

放假回家的第一天,呵呵。

緬懷Stevens大師。

最好的參考資料:

1.師從互聯網。

2.Linux man 命令:man ? netlink,man rtnetlink。

3.UNP v1第18章?。

第一條:概述。

簡單說來,linux通過Netlink機制與內核中相應的模塊進行通信來掌控設備(網絡方面的居多)。

man手冊如是說:

Netlink ?is ?used ?to transfer information between kernel and

userspace?processes. ?It consists ?of ?a ?standard ?sockets-based

interface ?for?userspace processes and an internal kernel API for

kernel modules. ?The? internal kernel interface is not documented in

this manual page. ?There?is ?also ?an ?obsolete netlink interface via

netlink character devices;this interface is not documented here and is

only ?provided ?for ?backwards compatibility.

我翻譯的:

Netlink用于在內核和用戶空間的進程之間通信。Netlink機制由在用戶空間的SocketAPI和內核模塊的系統調用組成。手冊不提及內核的系統調用接口。至于,Netlink字符設備的接口API也沒說,Netlink字符設備的接口API是為了向后兼容。

另外:UNPv1第18章的路由Socket不適用于Linux,linux使用netlink機制全面代替BSD的路由套接口機制。

#define

PF_ROUTE

PF_NETLINK /* Alias to emulate 4.4BSD. ?*/

題外話:什么是套接字?即IP地址和端口的組合。

第二條:Netlink套接字描述符

int sockfd = socket(AF_NETLINK, sock_type, netlink_faimly);

1.sock_type

:man手冊中說:Netlink ?is ?a datagram-oriented

service。netlink機制是面向數據報的服務,故可以使用SOCK_RAW

和SOCK_DGRAM,不能使用SOCK_STREAM。手冊中也提到:netlink機制不區分數據報(datagram)套接字和原始(raw)套

接字。

2.netlink_faimly

:指定與哪個內核模塊進行通信的協議,如下:

NETLINK_ROUTE:路由 daemon

Receives routing and link updates and may be used to

modify ?the?routing ?tables (both IPv4 and IPv6), IP addresses, link

parameters, neighbor setups, queueing disciplines, traffic

classes and??packet classifiers (see rtnetlink(7)).

NETLINK_W1:1-wire 子系統

Messages from 1-wire subsystem.

NETLINK_USERSOCK:用戶態 socket 協議

Reserved for user-mode socket protocols.

NETLINK_FIREWALL:防火墻

Transport ?IPv4 ?packets ?from ?netfilter to userspace. ?Used by??ip_queue kernel module.

NETLINK_INET_DIAG:socket 監視

INET socket monitoring.

NETLINK_NFLOG:netfilter 日志

Netfilter/iptables ULOG.

NETLINK_XFRM:ipsec 安全策略

IPsec.

NETLINK_SELINUX:SELinux 事件通知

SELinux event notifications.

NETLINK_ISCSI:iSCSI 子系統

Open-iSCSI.

NETLINK_AUDIT:進程審計

Auditing.

NETLINK_FIB_LOOKUP:轉發信息表查詢

Access to FIB lookup from userspace.

NETLINK_CONNECTOR:netlink connector

Kernel connector. ?See Documentation/connector/* in ?the ?kernel?source for further information.

NETLINK_NETFILTER:netfilter 子系統

Netfilter subsystem.

NETLINK_IP6_FW:IPv6 防火墻

Transport ?IPv6 ?packets ?from ?netfilter to userspace. ?Used by??ip6_queue kernel module.

NETLINK_DNRTMSG:DECnet 路由信息

DECnet routing messages.

NETLINK_KOBJECT_UEVENT:內核事件向用戶態通知

Kernel messages to userspace.

NETLINK_GENERIC:通用 netlink

Generic netlink family for simplified netlink usage.

函數close用于關閉打開的netlink socket。

第三條:Netlink 套接字地址結構

#inlcude

struct sockaddr_nl {//幾乎和TCP里的sockaddr一樣。

sa_family_t

nl_family;

/* 必須為AF_NETLINK或PF_NETLINK

*/

unsigned short

nl_pad;

/*保留未用,初始為0

*/

__u32

nl_pid;

/* port ID,*/

__u32

nl_groups;

/* multicast groups mask 多播 組掩碼 */

};

nl_pid:

1.當作為bind函數的參數時,就是給沒有名字的socketfd賦上一個名字,只有一個要求在有多個Netlink

socketfd時要保證唯一性,方式一:由用戶保證唯一性:一個進程只有一個Netlink

socketfd時可以指定nl_pid為任意整數,getpid()是個不錯的選擇。但是一個進程有多個Netlinksocketfd時

就不能都指定為getpid(),必須加以區別。方式二:man手冊指出當把nl_pid賦為0,無論一個進程內有幾個?Netlink

socketfd,內核將保證他們唯一性。

2.作為sendto等函數的參數:是用來指定發送數據目的地,當目的地是其他的進程,就賦上那個進程的pid就可,這個幾乎用不到。當放送到內核,直接賦為0.

nl_groups:

對于Netlink 的每個協議,都有一個容納32個多播組的集合。nl_groups的一個二進制位代表一個組,共有32個。

1.作為bind 函數的參數,用于把調用進程加入到該nl_groups指定的多播組(是否可以同時被添加進多個組,就是nl_groups多位為1,未驗證),如果設置為 0,表示調用者不加入任何多播組。

2.作為sendto等函數的參數時。若nl_groups為0,配合nl_pid發送單播數據,當nl_groups不為0,配合nl_pid發送多播。

第四條:Netlink消息。

Netlink與內核通信的消息有兩部分:首部和數據。

首先,Netlink socket 和TCP協議中接收放送數據一樣,也需要首部。主要用于多路復用和多路分解,以及其它的一些控制。

struct nlmsghdr {

//這個結構就是用于表示首部(頭部)。

__u32 nlmsg_len; ? ?/* Length of message including header. 整個數據的大小,包括這個首部和要接收/發送的數據*/

__u16 nlmsg_type; ? /* Type of message content.?接收/發送數據的用途 */

__u16 nlmsg_flags; ?/* Additional flags. 附加標志*/

__u32 nlmsg_seq; ? ?/* Sequence number. 序列號,就是這個消息是第幾個*/

__u32 nlmsg_pid; ? ?/* PID of the sending process. */

};

nlmsg_seq 和 nlmsg_pid 用于應用追蹤消息,前者表示順序號,后者為消息來源進程 ID。

如果一個消息是由多個數據報組成,也就是說這個消息有多個首部,當然每個首部后面跟著數據部分。那么除了最后數據報,每個部分的首部都要在

nlmsg_flags設置NLM_F_MULTI,最后數據報的首部nlmsg_type設置為NLMSG_DONE。這種情況多是由內核向用戶空間造

成的,所以這些標志一般都是由內核賦值的我們不需要賦值,只在接收消息檢測這些標志位。

nlmsg_type:取值如下:

以下四個值一般由內核設置,用于我們接收數據后,檢測。

1.NLMSG_NOOP :?message?is ?to be ignored;這個消息類型表示數據內容為空,應用可以忽略該報文

2.NLMSG_ERROR:message signals an error and the payload?contains an nlmsgerr structure?這個消息類型表示數據部分是一個錯誤信息,數據部分的結構如下

struct nlmsgerr{

int error; /* Negative errno or 0 for acknowledgements;負數表示的出錯號 errno 或為 0 要求確認 acks*/

struct nlmsghdr msg; /* Message header that caused the error:造成出錯的消息報頭*/

};

3.NLMSG_DONE :

message terminates a ?multipart message.在我們接收或者發送消息給內核的時候,可能一次發送多個報文,這個消息類型標志最后一個報文。

4.NLMSG_OVERRUN

:?Data lost。

以下是由程序員設置的,這里的是NETLINK_ROUTE協議支持的類型,至于其他協議的有待研究,每種類型對應著后面數據部分的不同承載結構。使用NETLINK_ROUTE協議時候支持的類型如下,他們都定義在linux/rtnetlink.h中:

1.Link Layer:創建,刪除、獲取、設置網絡設備的信息:RTM_NEWLINK, RTM_DELLINK, RTM_GETLINK,RTM_SETLINK

對應數據部分數據結構:在linux/rtnetlink.h中

struct ifinfomsg {/* struct ifinfomsg?passes link level specific information, not dependent?on network protocol.*/

unsigned char

ifi_family;

unsigned char

__ifi_pad;

unsigned short

ifi_type;

/* ARPHRD_* */

int

ifi_index;

/* Link index

*/

unsigned

ifi_flags;

/* IFF_* flags

*/

unsigned

ifi_change;

/* IFF_* change mask */

};

2.Address Settings:創建,刪除、獲取網絡設備的IP信息:RTM_NEWADDR, RTM_DELADDR, RTM_GETADDR

對應數據部分數據結構 :在linux/if_addr.h中

struct ifaddrmsg {

__u8

ifa_family;

__u8

ifa_prefixlen;

/* The prefix length

*/

__u8

ifa_flags;

/* Flags

*/

__u8

ifa_scope;

/* Address scope

*/

__u32

ifa_index;

/* Link index

*/

};

3.Routing Tables:?創建,刪除、獲取網絡設備的路由信息:RTM_NEWROUTE, RTM_DELROUTE, RTM_GETROUTE

對應數據部分數據結構 :在linux/rtnetlink.h中

struct rtmsg {//Definitions used in routing table administration.

unsigned char

rtm_family;/* 路由表地址族 */

unsigned char

rtm_dst_len;?/* 目的長度 */

unsigned char

rtm_src_len;?/* 源長度 */

unsigned char

rtm_tos;?/* TOS */

unsigned char

rtm_table;

/* Routing table id */?/* 路由表選取 */

unsigned char

rtm_protocol;

/* Routing protocol; see below

*//* 路由協議 */

unsigned char

rtm_scope;

/* See below */

unsigned char

rtm_type;

/* See below

*/

unsigned

rtm_flags;

};

4.Neighbor Cache:創建,刪除、獲取網絡設備的相鄰信息:RTM_NEWNEIGH, RTM_DELNEIGH, RTM_GETNEIGH

對應數據部分數據結構 :在linux/neighbour.h中

struct ndmsg {

__u8

ndm_family;

__u8

ndm_pad1;

__u16

ndm_pad2;

__s32

ndm_ifindex;

__u16

ndm_state;

__u8

ndm_flags;

__u8

ndm_type;

};

struct nda_cacheinfo {

__u32

ndm_confirmed;

__u32

ndm_used;

__u32

ndm_updated;

__u32

ndm_refcnt;

};

5.Routing Rules:創建,刪除、獲取路由規則信息:RTM_NEWRULE, RTM_DELRULE, RTM_GETRULE

對應數據部分數據結構 :在linux/rtnetlink.h中struct rtmsg

6.Queuing Discipline Settings:創建,刪除、獲取隊列的原則:RTM_NEWQDISC, RTM_DELQDISC, RTM_GETQDISC

對應數據部分數據結構 :在linux/rtnetlink.h中

struct tcmsg {//Traffic control messages.

unsigned char

tcm_family;

unsigned char

tcm__pad1;

unsigned short

tcm__pad2;

int

tcm_ifindex;

__u32

tcm_handle;

__u32

tcm_parent;

__u32

tcm_info;

};

7.Traffic Classes used with Queues:創建,刪除、獲取流量的類別:RTM_NEWTCLASS, RTM_DELTCLASS, RTM_GETTCLASS

對應數據部分數據結構 :linux/rtnetlink.h中struct tcmsg

8.Traffic filters:創建,刪除、獲取流量的過慮:RTM_NEWTFILTER, RTM_DELTFILTER, RTM_GETTFILTER

對應數據部分數據結構 :?linux/rtnetlink.h中struct tcmsg

9.Others:?RTM_NEWACTION

,?RTM_DELACTION

,?RTM_GETACTION

,?RTM_NEWPREFIX

,?RTM_GETPREFIX

,?RTM_GETMULTICAST

,

RTM_GETANYCAST

,RTM_NEWNEIGHTBL

,RTM_GETNEIGHTBL

,?RTM_SETNEIGHTBL

nlmsg_flags:這個成員用于控制和表示消息,

值如下:

1.Standard flag bits in nlmsg_flags

NLM_F_REQUEST ? Must be set on all request messages.表示消息是一個請求,所有應用首先發起的消息都應設置該標志。,這個標志可以和以下的一個標志組合

NLM_F_ROOT??被許多 netlink

協議的各種數據獲取操作使用,該標志指示被請求的數據表應當整體返回用戶應用,而不是一個條目一個條目地返回。有該標志的請求通常導致響應消息設置

NLM_F_MULTI標志。注意,當設置了該標志時,請求是協議特定的,因此,需要在字段 nlmsg_type 中指定協議類型。

NLM_F_MATCH??表示該協議特定的請求只需要一個數據子集,數據子集由指定的協議特定的過濾器來匹配。

NLM_F_ATOMIC 返回對象表的快照

NLM_F_DUMP 被定義為NLM_F_ROOT|NLM_F_MATCH

NLM_F_REPLACE?用于取代在數據表中的現有條目。

NLM_F_EXCL?用于和 CREATE 和 APPEND 配合使用,如果條目已經存在,將失敗。

NLM_F_CREAT??指示應當在指定的表中創建一個條目。

NLM_F_APPEND?指示在表末尾添加新的條目。

NLM_F_MULTI ? ? The ?message ?is part of a multipart message

terminated by NLMSG_DONE.

用于指示該消息是一個多部分消息的一部分,后續的消息可以通過宏NLMSG_NEXT來獲得。

NLM_F_ACK ? ? ? Request for an acknowledgment on success.表示該消息是前一個請求消息的響應,順序號與進程ID可以把請求與響應關聯起來。

NLM_F_ECHO ? ? ?Echo this request.表示該消息是相關的一個包的回傳。

2.Additional flag bits for GET requests

NLM_F_ROOT ? ? Return the complete table instead of a single entry.

NLM_F_MATCH ? ?Return all entries matching ?criteria(標準,要求)

passed ?in ?message?content. ?Not implemented yet.

NLM_F_ATOMIC ? Return an atomic snapshot of the table.

NLM_F_DUMP ? ? Convenience macro; equivalent to (NLM_F_ROOT|NLM_F_MATCH).

Note ?that ?NLM_F_ATOMIC ?requires ?the ?CAP_NET_ADMIN capability or an? effective UID of 0.

3.Additional flag bits for NEW requests

NLM_F_REPLACE ? Replace existing matching object.

NLM_F_EXCL ? ? ?Don't replace if the object already exists.

NLM_F_CREATE ? ?Create object if it doesn't already exist.

NLM_F_APPEND ? ?Add to the end of the object list.

第五條Netlink與內核通信

Linux定義了多個宏,來輔助我們發送和接收Netlink消息,與內核進行通信。

#include

#include

1.int NLMSG_ALIGN(size_t len);

#define NLMSG_ALIGNTO

4

#define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) )

//宏NLMSG_ALIGN(len)用于得到不小于len且字節對齊的最小數值。

2.#define NLMSG_HDRLEN

((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))

//頭部長度

3.int NLMSG_LENGTH(size_t len);

#define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(NLMSG_HDRLEN))

//宏NLMSG_LENGTH(len)用于計算數據部分長度為len時實際的消息長度。它一般用于分配消息緩存。

4.int NLMSG_SPACE(size_t len);

#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len))

//宏NLMSG_SPACE(len)返回不小于NLMSG_LENGTH(len)且字節對齊的最小數值,它也用于分配消息緩存。

5.void *NLMSG_DATA(struct nlmsghdr *nlh);

#define NLMSG_DATA(nlh) ?((void*)(((char*)nlh) + NLMSG_LENGTH(0)))

//宏NLMSG_DATA(nlh)用于取得消息的數據部分的首地址,設置和讀取消息數據部分時需要使用該宏。

6.struct nlmsghdr *NLMSG_NEXT(struct nlmsghdr *nlh, int len);

#define NLMSG_NEXT(nlh,len)

((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), ??(struct nlmsghdr*)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))

//宏NLMSG_NEXT(nlh,len)用于得到下一個消息的首地址,同時len也減少為剩余消息的總長度,該宏一般在一個消息被分成幾個部分發送或接收時使用。

7.int NLMSG_OK(struct nlmsghdr *nlh, int len);

#define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr)

&&?(nlh)->nlmsg_len >= sizeof(struct nlmsghdr)

&&??(nlh)->nlmsg_len <= (len))

//宏NLMSG_OK(nlh,len)用于判斷消息是否有len這么長。

8.int NLMSG_PAYLOAD(struct nlmsghdr *nlh, int len);

#define NLMSG_PAYLOAD(nlh,len) ((nlh)->nlmsg_len - NLMSG_SPACE((len)))

//宏NLMSG_PAYLOAD(nlh,len)用于返回payload的長度。

設置好上面消息后,我們就可以用sendto和recv分別發送和接收數據了。

總結

以上是生活随笔為你收集整理的Linux网络设备描述符,Linux的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。