原始套接字数据链路层访问

news/2024/7/23 11:09:16

1. 原始套接字能力:

(1) 进程可以读写ICMP,IGMP等分组,如ping程序;

(2) 进程可以读写内核不处理协议字段的ipv4数据报;如OSPF等;

(3) 进程可以使用IP_HDRINCL套接字选项自行构造ipv4首部;

 

2. 原始套接字的创建:

int sockfd;
sockfd = socket(AF_INET, SOCK_RAW, protocol);

 

开启ip头构造选项:

const int on = 1;
if (setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0){
    error...
}

当选项开启时,我们需要构造完整的IP首部,下列情况除外:

(1) IP总是计算并存储IP首部校验和;

(2) 如果我们将IP标识字段设置为0,内核将设置该字段;

(3) 如果源ip地址是INADDR_ANY,IP将把它设置为外出接口的IP地址;

(4) 如何设置IP选项取决于实现。有些实现取出我们预先使用IP_OPTIONS套接字选项设置的任何IP选项,把它们添加到我们的构造首部中,而其他实现则要求我们亲自在首部指定任何期望的IP选项;

(5) IP首部中的有些字段必须以主机字节序填写,有些字段必须以网络字节序填写,具体取决于实现。linux上所有字节都采用网络字节序;

 

3. 原始套接字的输出:

(1) 普通输出通过调用sendto或者sendmsg并指定目的IP地址完成,如果套接字已经连接,那么也可以使用write,writev,send;

(2) 如果IP_HDRINCL套接字选项未开启,那么由进程让内核发送的数据的起始地址是IP首部之后的第一个字节,因为内核将构造IP首部并把它置于来自进程的数据之前。内把所构造的ipv4首部的协议字段设置成来自socket调用的第三个参数;

(3) 如果IP_HDRINCL套接字选项已开启,那么由进程让内核发送的数据的起始地址是IP首部的第一个字节。进程调用输出函数写出的数据量必须包括IP首部大小。整个IP首部由进程构造。不过(a)ipv4标识字段可以设置为0,从而告知内核设置该值;(b) ipv4首部校验和字段总是由内核计算并存储 (c) ipv4选项字段是可选的;

(4) 内核会对超出外出接口MTU的原始分组执行分片;

 另:ip首部之后所含有的其他任何首部的校验和需要用户进程计算;

 

4. 原始套接字的输入:

(1) 接收到的udp/tcp分组决不传递到任何原始套接字;进程只能通过数据链路层读取这些分组;但是可以发哦;

(2) 大多数icmp分组在内核处理完其中的icmp消息后传递到原始套接字;源自Berkeley的实现把不是回射请求,时间戳请求或者地址掩码请求(这三类均有内核处理)的所有接收到的icmp分组传递给原始套接字;

(3) 所有igmp分组在内核完成处理其中的igmp消息后传递给原始套接字;

(4) 内核不认识协议字段的所有ip数据报传递到原始套接字;内核对这些分组进行ip头最小验证:ip版本,ip校验和,首部长度,目的ip地址;

(5) 如果某个数据报以片段的形式到达,那么在它的所有片段均到达并重组出该数据报之前,不会传递任何片段分组到原始套接字;

(6) 如果创建原始套接字制定了非0协议参数,那么接收到的数据报协议字段必须匹配该值,否则该数据报不会传递到该套接字;

(7) 如果原始套接字已由bind调用绑定了某个本地ip地址,那么接收到的数据报目的IP地址必须匹配这个绑定地址,否则该数据报不会传递到这个套接字;

(8) 如果这个原始套接字由connect调用制定了某个外地ip地址,那么接收到的数据报的源ip地址必须匹配该连接,否则数据报不会传递到该套接字;

注意:如果一个原始套接字是以0值协议参数创建,并且既未调用bind,也未调用connect,那么该套接字将接收可由内核传递到原始套接字的每个原始数据报的一个副本;

无论何时往一个原始IPv4套接字传递一个接收的数据报,传到该套接字所在进程都包括ip首部在内的完整数据报;ipv6不包含首部;

 

5. 数据链路层访问:

接收所有帧:

fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

 

接收ipv4帧:

fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));

 

注意:如果设置接口为混杂模式,则可接收所有经过数据流,而不论其目的地址是否是它;

 

转载于:https://www.cnblogs.com/wanpengcoder/p/5372018.html


http://www.niftyadmin.cn/n/2496170.html

相关文章

mysql 锁 连接数_mysql查询最大连接数及锁

1、查看最大连接数show variables like %max_connections%;2、修改最大连接数set GLOBAL max_connections 200;3.root 查看所有用户当前连接-- show processlist;只列出前100条&#xff0c;如果想全列出请使用show full processlist; show processlist;4.查看常用监控语句命令…

AOJ 802.运输宝物

G. 运输宝物Time Limit: 1000 ms Case Time Limit: 1000 ms Memory Limit: 64 MBTotal Submission: 53 Submission Accepted: 22Description众所周知&#xff0c;“西瓜”是大名鼎鼎的江洋大盗。有一次他偷到了一批宝库。这批宝物共有n个&#xff0c;他一共有k个箱子。他…

最佳课题选择

最佳课题选择 时间限制: 1 Sec 内存限制: 128 MB题目描述 Matrix67要在下个月交给老师n篇论文&#xff0c;论文的内容可以从m个课题中选择。由于课题数有限&#xff0c;Matrix67不得不重复选择一些课题。完成不同课题的论文所花的时间不同。具体地说&#xff0c;对于某个课题i…

python正则表达式简述

正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则&#xff0c;凡是符合规则的字符串&#xff0c;我们就认为它“匹配”了&#xff0c;否则&#xff0c;该字符串就是不合法的。所以我们判断一个字符串是否是合法的Email的…

Cannot assign requested address的解决办法

今天想试一下redis&#xff0c;写了个程序&#xff0c;对redis连续进行100000访问&#xff0c;却出现以了Cannot assign requested address的问题&#xff0c;我起先是以为是redis的问题&#xff08;可能承受不了这么多访问量&#xff09;&#xff0c;可是redis被大家吹的那么N…

查询mysql版本 for mac_MySQL(InnoDB、MyISAM)和MongoDB的性能测试

软硬件环境MySQL版本&#xff1a;5.1.50&#xff0c;驱动版本&#xff1a;5.1.6(最新的5.1.13有很多杂七杂八的问题)MongoDB版本&#xff1a;1.6.2&#xff0c;驱动版本&#xff1a;2.1操作系统&#xff1a;Windows XP SP3(这个影响应该不大)CPU&#xff1a;Intel Core2 E6550 …

Linux命令 uname:查看系统与内核相关信息

zhzh:~$uname --help zhzh:~$uname -a //所有系统相关的信息 转载于:https://www.cnblogs.com/onelikeone/p/6917733.html

wcf 数据契约_【DDD】跟我一起学WCF(9)——WCF回调操作的实现

一、引言在上一篇文章中介绍了WCF对Session的支持&#xff0c;在这篇文章中将详细介绍WCF支持的操作。在WCF中&#xff0c;除了支持经典的请求/应答模式外&#xff0c;还提供了对单向操作、双向回调操作模式的支持&#xff0c;此外还有流操作的支持。接下来将详细介绍下这几种操…