IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> SADP功能使用 -> 正文阅读

[网络协议]SADP功能使用

SADP主要使用的是链路层多播及UDP多播的原理进行实现的。

1.链路层多播

socket(PF_PACKET, SOCK_RAW, htons(0x8033))
PF_PACKET接口可以操作链路层的数据
使用SOCK_RAW发送的数据必须包含链路层的协议头,接受得到的数据包,包含链路层协议头。而使用	    SOCK_DGRAM则都不含链路层的协议头。
0x8033指的是socket以广播协议发送
setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &Filter, sizeof(Filter)

第一个参数socket是套接字描述符。
第二个参数level是被设置的选项的级别,如果想要在套接字级别上设置选项,就必须把level设置为SOL_SOCKET。
第三个参数 option_name指定准备设置的选项,option_name可以有哪些常用取值,这取决于level,以linux 2.6内核为例(在不同的平台上,这种关系可能会有不同),在套接字级别上(SOL_SOCKET):
SO_ATTTACH_FILTER选项发送到内核,并且你的filter代码能通过内核的检查,这样你就可以立即过滤socket上面的数据了

Filter结构介绍
其中 *filter 指向结构为 struct sock_filter 的 BPF过滤代码(code)。

struct sock_fprog {
unsigned    short                 len; 
struct sock_filter  _user   *filter;
};

这样的结构被组装成一个4元数组,包含:code、jt、jf和K值。jt和jf是跳转偏移量,k是一个通用值提供给code使用。

struct sock_filter {    /* Filter block */
        __u16   code;   /* Actual filter code */
        __u8    jt;     /* Jump true */
        __u8    jf;     /* Jump false */
        __u32   k;      /* Generic multiuse field */
};
struct sock_filter BPF_code[]= {
        { 0x28, 0, 0, 0x0000000c },
        { 0x15, 0, 1, 0x00008033 },
        { 0x6, 0, 0, 0x00000200 }, 
        { 0x6, 0, 0, 0x00000000 }
 };

BPF(Berkeley Packet Filter)伯克利包过滤器。 BPF允许用户空间程序将一个过滤(filter)附加到任何的套接字(socket)上面用来允许或不允许某些类型的数据通过socket

tcpdump 是linux 中调试网络的一个工具, 实际上 tcpdump 就是用利用BPF原理编写的一个工具,所以tcpdump 提供了一个生成 bpf code 的选项 -dd 。
使用 tcpdump 命令加上 -dd 选项来生成 bpf code,命令格式如下:
tcpdump -dd -i eth0 port 22
在这里插入图片描述
注意:用tcpdump生成的BPF代码只能用于SOCK_RAW的socket,这类socket是可以直接操作数据链路层的。如果你打算将BPF用于ip层等较高层次的socket,那么你需要手工修改部分行的code.k,也就是修改如ldh [12]当中的[12]这个数值,因为这个数值的偏移量是按照从链路层开始计算得到的,在没有链路层之后,这个值就发生了变化,这个是需要注意的。
在这里插入图片描述
实现了让所有IPv4/IPv6 port 22的包通过,这个socket上所有其他的包将会被丢弃
tcpdump -dd -i eth0 port 22

在这里插入图片描述
链路层多播的发包实现方式
原理是利用AF_PACKET 套接字发送一个任意的以太网帧

   struct sockaddr_ll sa;

    memset(&sa, 0, sizeof(sa));
    sa.sll_family = AF_PACKET;
    sa.sll_ifindex = get_iface_index(p->fd, (const int8_t *)p->device[ifarr_idx]);
    sa.sll_protocol = htons(ETH_P_ALL);
    sendto(p->fd, packet, len, 0, (struct sockaddr *)&sa, sizeof(sa));

数据链路层的头信息通常定义在 sockaddr_ll 的结构体中,protocol是按照网络字节顺序(network byte order),大部分定义在头文件中,设置协议时,例如 htons(ETH_P_ALL)来接收所有的数据包;

UDP多播

socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)

AF_INET:监听udp协议的239.255.255.250,端口37020的报文
SOCK_DGRAM:socket设置为UDP数据包
IPPROTO_UDP :socket走 UDP协议进行数据收发
局部多播地址:在224.0.0.0~224.0.0.255之间,这是为路由协议和其他用途保留的地址,
路由器并不转发属于此范围的IP包。

预留多播地址:在224.0.1.0~238.255.255.255之间,可用于全球范围(如Internet)或网
络协议。

管理权限多播地址:在239.0.0.0~239.255.255.255之间,可供组织内部使用,类似于私
有IP地址,不能用于Internet,可限制多播范围

setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &so_reuseaddr, sizeof(so_reuseaddr)

SO_REUSEADDR套接字选项能起到以下4个不同的功用。
(1)SO_REUSEADDR允许启动一个监听服务器并捆绑其众所周知的端口,即使以前建立的将该端口用作他们的本地端口的连接仍存在。这个条件通常是这样碰到的:

(a)启动一个监听服务器;
(b)连接请求到达,派生一个子进程来处理这个客户;
(c)监听服务器终止,但子进程继续为现有连接上的客户提供服务;
(d)重启监听服务器。

默认情况下,当监听服务器在步骤d通过调用socket,bind和listen重新启动时,由于他试图捆绑一个现有连接(即正由早先派生的那个子进程处理着的连接)上的端口,从而bind调用会失败。但是如果该服务器在socket和bind两个调用之间设置了SO_REUSEADDR套接字选项,那么将成功。所有TCP服务器都应该指定本套接字选项,以允许服务器在这种情况下被重新启动。

(2)SO_REUSEADDR允许在同一端口上启动同一服务器的多个实例,只要每个实例捆绑一个不同的本地IP地址即可。对于TCP,我们绝对不可能启动捆绑相同IP地址和相同端口号的多个服务器:这是完全重复的捆绑,即使我们给第二个服务器设置了SO_REUSEADDR套接字也不管用。

(3)SO_REUSEADDR 允许单个进程捆绑同一端口到多个套接字上,只要每次捆绑指定不同的本地IP地址即可。

(4)SO_REUSEADDR允许完全重复的捆绑:当一个IP地址和端口号已绑定到某个套接字上时,如果传输协议支持,同样的IP地址和端口还可以捆绑到另一个套接字上。一般来说本特性仅支持UDP套接字。

setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)setsockopt(sock,IPPROTO_IP,IP_MULTICAST_LOOP,&loop,sizeof(loop)setsockopt(sock,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)setsockopt(iSockFd, SOL_SOCKET, SO_BINDTODEVICE,(char *)&interface, sizeof(interface)

1.选项IP_MULTICASE_TTL
选项IP_MULTICAST_TTL允许设置超时TTL,范围为0~255之间的任何值,例如:

unsigned char ttl=255;
setsockopt(s,IPPROTO_IP,IP_MULTICAST_TTL,&ttl,sizeof(ttl));

2.选项IP_MULTICAST_LOOP
IP_MULTICAST_LOOP 应用到接收端.在接收端启用IP_MULTICAST_LOOP. loop设置为1,表示接收自身发送出去的数据,设置为0表示不接收

3.选项IP_ADD_MEMBERSHIP和IP_DROP_MEMBERSHIP
加入或者退出一个组播组,通过选项IP_ADD_MEMBERSHIP和IP_DROP_MEMBER- SHIP,对一个结构struct ip_mreq类型的变量进行控制,struct ip_mreq原型如下:

struct ip_mreq          
{
      struct in_addr imn_multiaddr;      /*加入或者退出的广播组IP地址*/
      struct in_addr imr_interface;      /*加入或者退出的网络接口IP地址*/
};

选项IP_ADD_MEMBERSHIP用于加入某个广播组,之后就可以向这个广播组发送数据或者从广播组接收数据。此选项的值为mreq结构,成员imn_multiaddr是需要加入的广播组IP地址,成员imr_interface是本机需要加入广播组的网络接口IP地址。例如:

struct ip_mreq mreq;
setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq));

使用IP_ADD_MEMBERSHIP选项每次只能加入一个网络接口的IP地址到多播组,但并不是一个多播组仅允许一个主机IP地址加入,可以多次调用IP_ADD_MEMBERSHIP选项来实现多个IP地址加入同一个广播组,或者同一个IP地址加入多个广播组。当imr_ interface为INADDR_ANY时,选择的是默认组播接口。
4.选项SO_BINDTODEVICE
当套接口被绑定到指定的网络设备接口之后,只有来自该设备的数据包才会被套接口处理

如果有多个接口,例如eth0, eth1, ethx…,就可以在创建套接字的时候绑定相应的接口发送数据,网关端目前使用的eth2

int c;
struct sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr(pClientAddr);
sa.sin_port = htons(port);
  
c = sendto(p->fd, packet, len, 0, (struct sockaddr *)&sa, sizeof(sa));
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-11-20 18:45:47  更:2021-11-20 18:47:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年7日历 -2024/7/3 21:25:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码