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分别发送和接收数据了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/426443.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android计时器

熟悉和掌握Android线程的使用 实验要求&#xff1a; 完成一个秒表&#xff0c;具备启停功能&#xff0c;正确使用工作线程完成界面刷新 分析秒表的计时是否准确&#xff0c;原因是什么&#xff0c;如何保证秒表计时准确 代码实现&#xff1a; &#xff08;1&#xff09;Activit…

java学习(81):静态代码块

//静态代码块class test16 {private static final String URL;private static final String DEVICE;private static final String USER;private static final String ROOT;static test16 self;static {URL"歌谣";DEVICE"笔记本电脑";USER"root";…

linux用echo显示欢迎信息,我使用过的Linux命令之echo - 显示文本、打印信息

&#xfeff;&#xfeff;用途说明echo命令用来打印信息&#xff0c;是一个最常用的命令。在命令行中常用来打印环境变量的值&#xff0c;已确定当前环境中是否设置了指定的环境变量。在shell脚本中&#xff0c;常用来打印信息和帮助调试程序。常用参数-n 打印信息之后不换行。…

LeetCode 169. Majority Element

LeetCode 169. Majority Element 分析 难度 易 来源 https://leetcode.com/problems/majority-element/ JDK里的排序算法&#xff0c;效率就是高啊 题目 Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊…

java学习(82):静态代码块内部类

//静态代码块内部类 public class test18{private static final String URL;private static final String DEVICE;private static final String USER;private static final String ROOT;static test18 self;static {class Inner{public void printMessage(){System.out.println…

linux进程管理fork,Linux -- 进程管理之 fork() 函数

一个进程调用fork()函数后&#xff0c;系统先给新的进程分配资源&#xff0c;例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中&#xff0c;只有少数值与原来的进程的值不同。相当于克隆了一个自己。Test1for(int i 0; i<2; i){if(fork() 0)print…

java学习(83):常用基础类object

//常用基础类 public class ObjectClass {private String name;private int age;public void say(){System.out.println(name);System.out.println(age);}public void setAge(int age) {this.age age;}public int getAge() {return age;}public void setName(String name) {th…

Elasticsearch及相关插件的安装

Elasticsearch及相关插件的安装 1、安装Elasticsearch并启动服务 2、安装第三方插件 2.1、Head插件 是Elasticsearch的一个集群管理工具&#xff0c;可以通过它来查看和搜索ES的数据&#xff0c;是完全由html5编写的独立网页程序。 2.2、Bigdesk插件 是Elasticsearch的一个集群…

linux上git克隆命令,Git clone命令用法

git clone是git中常用的命令&#xff0c;其作用是将存储库克隆到新目录中。那么在git中&#xff0c;git clone具体该如何用呢?更快更轻松的学习Git,请点击Git微课git clone命令的作用是将存储库克隆到新目录中&#xff0c;为克隆的存储库中的每个分支创建远程跟踪分支(使用git…

java学习(84):object常用方法tostring,equals,hashcode

//object常用方法 public class test21 {public static void main(String[] args) {Object obj new Object();ObjectCl usr new ObjectCl();usr.setAge(6);usr.setName("歌谣");usr.say();//tostringString str usr.toString();System.out.println(str);//equalsO…

《写给大家看的设计书》(第四版)

今天读完了《写给大家看的设计书》&#xff08;第四版&#xff09;&#xff0c;Robin Williamy用浅显易懂的语言和例子&#xff0c;给我们展示了设计中的基本原则&#xff0c;以下做一个简单的记录和总结。 设计中需要遵循的四个原则&#xff0c;其实很多都是我们在设计中已经实…

linux不支持32,Visual Studio Code 1.36发布,不再支持Linux 32位

VS Code 1.36&#xff0c;即2019年6月发布的Visual Studio Code&#xff0c;已发布。新版本已更新至Electron 4.x&#xff0c;意味着它将不再在Linux 32位上运行。现在可以将文件夹从VS Code外部拖放到文件资源管理器中进行复制。 以前&#xff0c;在将文件夹放入VS Code Explo…

java学习(85):Interage包装类基本使用

测试类 public class test22 {public static void main(String[] args){int num5;Integer obj1new Integer(num);System.out.println("obj1的值为"obj1);Integer obj2100;System.out.println("obj2的值为"obj2);Integer obj3new Integer("-789"…

php 安装rabtmq amqp 扩展

php 安装 rabbitmq-c-0.9.0 扩展 安装 ibrabbitmq-c github 仓库地址https://github.com/alanxz/rab... 安装过程如果报错 [ 87%] Built target amqp-get Scanning dependencies of target amqp-publish [ 88%] Building C object tools/CMakeFiles/amqp-publish.dir/publis…

linux 调用rest接口,REST调用

1. 概述与SOAP相比&#xff0c;REST WebService简化了调用&#xff0c;也降低了技能要求。REST 近年来已经成为最主要的 Web 服务设计模式。 事实上&#xff0c;REST 对 Web 的影响非常大&#xff0c;由于其使用相当方便&#xff0c;已经普遍地取代了基于 SOAP 和 WSDL 的接口设…

关于JWT(Json Web Token)的思考及使用心得

什么是JWT&#xff1f; JWT(Json Web Token)是一个开放的数据交换验证标准rfc7519(php 后端实现JWT认证方法一般用来做轻量级的API鉴权。由于许多API接口设计是遵循无状态的(比如Restful)&#xff0c;所以JWT是Cookie Session这一套机制的替代方案。 组成 JWT由三部分组成头部(…

java学习(86):Interage方法compareto,parseint,intvalue

public class test22 {public static void main(String[] args){int num5;Integer obj1new Integer(num);System.out.println("obj1的值为"obj1);Integer obj2100;System.out.println("obj2的值为"obj2);Integer obj3new Integer("-789");System…

西北民族大学c语言程序设计复试科目,2016年西北民族大学中国民族信息技术研究院962C语言程序设计复试笔试仿真模拟题...

一、选择题1&#xff0e; 有如下程序&#xff1a;程序运行后的输出结果是( )。答:D【解析】程序执行过程为:定义结构体变量将ABC , 故D 项正确。2&#xff0e; 有以下程序第 2 页&#xff0c;共 33 页 调用strcpy函数为结构体成员赋值最后输出结果为赋值给程序运行后的输出结果…

JAVA四则运算(读写文件)

完成时间&#xff1a;17&#xff1a;10 package 四则运算试题;import java.io.BufferedReader; import java.io.PrintStream; import java.util.Scanner; import java.io.FileReader; import java.io.IOException; public class jisuanti {public static void main(String[] ar…

java学习(87):Interage包装类进制转换

public class test22 {public static void main(String[] args){int num5;Integer obj1new Integer(num);System.out.println("obj1的值为"obj1);Integer obj2100;System.out.println("obj2的值为"obj2);Integer obj3new Integer("-789");System…