Socket选项设置含义
cc++socket函数详解

cc++socket函数详解c/c++ socket函数详解注意: 使⽤socketAPI前,要先将相关链接库(Ws2_32.lib)加⼊链接,并使⽤WSAStartUp函数初始化。
在linux中地址结构体sockaddr的结构与windows的不太⼀样,具体请百度每个socket函数都可能失败(返回-1),需要判断结果socket分成两种:⼀种专门⽤来监听新链接(或新活动),这种socket叫做master socket,⼀般只存在于服务器⼀种专门⽤来收发数据,这种socket叫做connected socket,客户端和服务器都存在int socket(int af,int type,int protocol);// 建⽴⼀个socket⽤于连接af:address family,如AF_INETtype:连接类型,通常是SOCK_STREAM或SOCK_DGRAMprotocol:协议类型,通常是IPPROTO_TCP或IPPROTO_UDP// 返回值:socket的编号,为-1表⽰失败int bind(int socket,sockaddr * address,uint addrlen);// 将⼀个地址和⼀个端⼝号绑定到⼀个socket连接上// socket:之前创建的socket// sockaddr:⼀个⽤来存放Ip地址和端⼝号的结构体// addrlen:上述结构体的长度// 返回值:为-1表⽰失败,若端⼝被占⽤,会从新绑定⼀个随机端⼝(仍返回失败)// 地址绑定为0表⽰绑定本机所有IPint sendto(int socket,char * buf,uint buflen,int flag,sockaddr * address,uint addrlen);【仅UDP】// 向⼀个指定的地址发送缓冲区内指定长度的消息// socket:之前创建的socket// buf:要发送的缓冲区// buflen:要发送的长度// flag:⼀般为0// sockaddr:⽬标地址// addrlen:上述结构体的长度// 返回值:发送出去的长度int recvfrom(int socket,char * buf,uint buflen,int flag,sockaddr * fromaddr,int * addrlen);【阻塞】【仅UDP】// 接收消息,可以获取发送⽅的地址// fromaddr:发送⽅地址(输出参数)// addrlen:发送⽅地址结构体的长度(输⼊输出参数)// 返回值:>0表⽰收到的字节数,=0表⽰连接被关闭,-1表⽰出错int recv(int socket,char * buf,uint buflen,int flag);【阻塞】// UDP时:接收任何⼀个发送到该socket的消息(⽆法获取发送⽅地址)// TCP时:接收⼀个已连接的socket (connected socket)发送的信息// socket:UDP时,为之前创建的socket,TCP时,为connected socket// buf:接收的缓冲区// buflen:缓冲区的长度// flag:⼀般为0// 返回值:>0表⽰收到的字节数,=0表⽰连接被关闭,-1表⽰出错// 注意:对于TCP,请确保socket是已连接的,因为只有已连接的socket会阻塞此函数// 该函数实际上是从缓冲区取指定长度的数据,如果缓冲区没有数据,则会阻塞;如果没有取完,则下次使⽤此函数的时候不会阻塞// 应注意:当⼀次⽆法获得对⽅发送的全部数据,在数据不完整的时候,程序可能⽆法向下执⾏,可以考虑将数据放在缓冲区中,等数据全部接收完成的时候再使⽤int getsockname(int socket,sockaddr * address,int * addrlen);// 获取指定socket上绑定的IP、端⼝信息(不能获取connected socket上的地址信息)// address:socket上绑定的地址(输出参数)// addrlen:socket上绑定的地址结构体的长度(输⼊输出参数)int getpeername(int socket,,sockaddr * address,int * addrlen);【仅TCP】// 获取⼀个已连接的socket的地址、端⼝信息// 参数含义同上struct sockaddr_in⼀个⽤来指定IP地址和端⼝号的结构体(不太好⽤,建议将其封装) family // 即address family,如AF_INET port // 端⼝号(注意要按位倒序,使⽤htons函数) sin_addr.S_un.S_addr // ⼀个为long类型的ip地址该结构体所有成员的字序为⽹络字序,低字节在前,⾼字节在后int listen(int socket,int maxconn);【仅TCP】【服务器】// 将⼀个socket设置为监听状态,专门⽤来监听的socket叫做master socket// maxconn:最⼤接收连接数// 返回值:失败返回-1,成功返回0int accept(int socket,sockaddr * fromaddr,int * addrlen);【阻塞】【仅TCP】【服务器】// 接收⼀个客户机的连接,返回⼀个socket,来⾃客户机的socket叫connected socket// socket:⽤来监听的socket(master socket)// fromaddr:客户机的地址信息// addrlen:地址结构体的长度(输⼊输出参数)// 返回值:返回⼀个新的socket,这个socket专门⽤来与此客户机通讯(connected socket)int connect(int socket,sockaddr * addr,int addrlen);【仅TCP】【客户端】// 使⽤当前socket连接⼀个地址(与服务器建⽴正式连接),此函数会触发服务器端的accept、select函数// 注意:服务端接收的socket值和客户端socket值不⼀样// addr:⼀般是服务器地址int send(int socket,char * buf,char buflen,int flag);【仅TCP】// 向⼀个已连接的socket发送信息,这个socket应该是connected socket(⾮master socket)int closesocket(int socket);// 关闭⼀个已存在的socket【正常关闭】// 失败返回-1,成功返回0UDP通讯流程WSAStartup()socket()bind()sendto(connected socket)/recv()/recvfrom()TCP通讯流程(服务器):WSAStartup()socket()bind()listen()accept()send()/recv()TCP通讯流程(客户端):WSAStartup()socket()bind()connect()send()/recv()。
Socket模拟Http连接 之 初识Socket

Socket模拟Http连接之初识Socket在Symbian上使用Socket需要库的支持,即你需要引入头文件es_sock.h和esock.lib库,准备一个活动对象类,比如class SocketConnection : public CActive(1)声明RSocketServ iSocketServ;它是用来连接Symbian系统中Soket服务的类,并不是我们一般意义上的Soc ketServer,在Symbian中实现类似于Java中SocketServer功能的类实际上是RSocket。
(2)连接系统的Socket服务,即,iSocket.Connect();(3)声明RSocket对象iSocket作为一个发送请求的SocketClient。
(4)打开连接(其实只是初始化RSocket对象,并不是真的打开了连接,连地址都没给呢,它上哪打开去啊~),即iSocket.Open(iSocketServ,KAfInet,KSockStream,KProtocolInetTcp); 方法中参数含义为,#param1 已经连接成功的Socket服务对象,即(1)中提到的iSocketServ;#param2 KAfInet,代表该套接字为因特网套接字;#param3 KSoc kStream 可靠的面向连接的套接字;#param4 KProtocolInetTcp TCP控制传输协议。
(5)编写连接方法,如SocketConnect(const TDesC& aServerName,TInt aServerPort);其中#param1 主机名称;# param2 主机端口,首先判断aServerName是否为IP地址,如果是则进入连接过程,如果不是则通过DNS对主机名进行解析从而得到IP地址,无论是连接还是解析,这两个过程都是异步的,故拦截或者取得解析结果都有在RunL中完成。
W5500(socket)寄存器使用说明

Socket 端口寄存器Sn3_MR (Socket n 模式寄存器) [R/W] [0x0000] [0x00]3, 4, 5, 6, 7). n is set ‘SNUM[2:0]’ in Control Bits sets.Sn_CR (Socket n 配置寄存器) [R/W] [0x0001] [0x00]该寄存器用于设置Socket n 的配置命令如OPEN、CLOSE、CONNECT、LISTEN、END 和RECEIVE。
经W5500 识别这一命令后,Sn_CR 寄存器会自动清零为0×00。
尽管Sn_CR 被清零为0×00,但命令仍在处理中。
为IR (中断寄存器) [R/W] [0x0015] [0x00]中断寄存器(IR)指明了中断的状态。
IR 的每一位都是‘0’,直到被主机写为‘1’.如果IR 不等于‘0×00’,INTn 引脚将会被拉低。
直到其变为‘0×00’时,INTn 才会被拉高。
S n_SR (Socket n 状态寄存器) [R] [0x0003] [0x00]Sn_SR指示了Socket n 的状态,并根据Sn_CR 或者一些TCP模式下的特殊控制包,如SYN,FIN 包而改变。
Sn_PORT (Socket n 源端口寄存器) [R/W] [0x0004-0x0005] [0x0000]该寄存器配置了Socket n 的源端口号。
当Socket n 工作在TCP 或UDP 模式下,该寄存器生效。
注意:必须在OPEN 命令生效前,完成对该寄存器的设置。
例) 如SOCKET 0 的端口=5000(0×1388),配置应如下,Sn_DHAR (Socket n 目的MAC 地址寄存器) [R/W] [0x0006-0x000B] [0xFFFFFFFFFFFF]Sn_DHAR 寄存器指示的为:UDP 模式下,使用Send_MAC 配置命令,配置Socket n的目标主机MAC 地址;或者CONNECT/SEND 配置命令,ARP 过程获取到的MAC 地址。
xinetd配置

}
----------------------------------
服务名一定要在/etc/services列出,并且要用使用合适的socket和协议。
日志中有几个值可以用于得到你的服务器的信息
表2不同的日志指示值
__________________________________________________________________________
3、对TELNET服务设置了资源限制,最多可用内存为8M,CPU每秒处理20个进程。
3.echo的配置
# default: off
#description: An echo server. This is thetcp\
#version.
service echo
{
disable = yes
type = INTERNAL
}
restart(){
stop
start
}
condrestart(){
[ -e /var/lock/subsys/xinetd] && restart
return 0
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
status)
xinetd配置实例xinetd的指示符指示符描述sockettype网络套接字类型流或者数据包protocolip协议通常是tcp或者udpwaityesno等同于inetd的waitnowaituser运行进程的用户idserver执行的完整路径serverargs传递给server的变量或者是值instances可以启动的实例的最大的值startmaxload负载均衡logonsuccess成功启动的登记选项logonfailure联机失败的时候的日志信息onlyfrom接受的网络或是主机noaccess拒绝访问的网络或是主机disabled用在默认的禁止服务logtype日志的类型和路径filesyslognice运行服务的优先级id日志中使用的服务名或者
tcp参数设置

tcp参数设置1. 参数含义参数描述默认值优化值net.core.rmem_default默认的TCP数据接收窗⼝⼤⼩(字节)。
229376256960net.core.rmem_max最⼤的TCP数据接收窗⼝(字节)。
131071513920net.core.wmem_default默认的TCP数据发送窗⼝⼤⼩(字节)。
229376256960net.core.wmem_max最⼤的TCP数据发送窗⼝(字节)。
131071513920dev_max_backlog 在每个⽹络接⼝接收数据包的速率⽐内核处理这些包的速率快时,允许送到队列的数据包的最⼤数⽬。
10002000net.core.somaxconn 定义了系统中每⼀个端⼝最⼤的监听队列的长度,这是个全局的参数。
1282048net.core.optmem_max表⽰每个套接字所允许的最⼤缓冲区的⼤⼩。
2048081920net.ipv4.tcp_mem 确定TCP栈应该如何反映内存使⽤,每个值的单位都是内存页(通常是4KB)。
第⼀个值是内存使⽤的下限;第⼆个值是内存压⼒模式开始对缓冲区使⽤应⽤压⼒的上限;第三个值是内存使⽤的上限。
在这个层次上可以将报⽂丢弃,从⽽减少对内存的使⽤。
对于较⼤的BDP可以增⼤这些值(注意,其单位是内存页⽽不是字节)。
94011125351188022131072262144524288net.ipv4.tcp_rmem 为⾃动调优定义socket使⽤的内存。
第⼀个值是为socket接收缓冲区分配的最少字节数;第⼆个值是默认值(该值会被rmem_default覆盖),缓冲区在系统负载不重的情况下可以增长到这个值;第三个值是接收缓冲区空间的最⼤字节数(该值会被rmem_max覆盖)。
409687380401123287602569604088000net.ipv4.tcp_wmem 为⾃动调优定义socket使⽤的内存。
socket的IP

socket的IPsocket有一个IP_TRANSPARENT选项,其含义就是可以使一个服务器程序侦听所有的IP地址,哪怕不是本机的IP地址,这个特性在实现透明代理服务器时十分有用,而其使用也很简单:int opt =1;setsockopt(server_socket,SOL_IP,IP_TRANSPARENT,&opt,sizeof(opt));0.导引:TCP绑定0.0.0.0的情况TCP可以绑定0.0.0.0,这个都知道,那么到底用哪一个地址何时确定呢?答案是“根据连接源的地址反向做路由查找后确定的”。
如果有一个地址A连接该服务器,那么在服务器收到syn后,就会查找目的地址为A的路由,进而确定源地址,然而如果不设置IP_TRANSPARENT选项,则这个被连接的地址必须在local路由表中被找到,否则一切都免谈。
因此如果我有一个没有设置IP_TRANSPARENT选项的TCP服务器绑定了0.0.0.0这个地址,端口绑定到80,我想这个服务器截获经过此地访问56.56.56.56:80的流量,怎么办?很简单,知道了TCP源地址选择的原理之后,我们只需要设置下面的路由即可:ip route add local 56.56.56.56 dev lo tab local这样一来,所有访问56.56.56.56这个地址的流量在经过本机时,都会进入local_in,因为它在local表中找到了路由。
但是本机没有56.56.56.56这个地址,本机的80端口服务器回复syn-ack的时候,执行反向路由查找,在local表中找到了56.56.56.56的路由,进而成功返回,最终连接成功在A和56.56.56.56:80之间建立。
然而思考一下,以上虽然圆满完成了任务,但是如果有N多个目的地址,岂不是要设置N多地址在local路由表?有没有什么办法只设置很少的规则就能截获所有到达80端口的流量呢?有的,那就是在代理服务器的socket上设置IP_TRANSPARENT选项。
socket套接字描述符 分配规则-概述说明以及解释

socket套接字描述符分配规则-概述说明以及解释1.引言1.1 概述概述:在计算机网络中,套接字是实现网络通信的一种机制,它允许不同的计算机之间通过网络进行数据传输和交互。
套接字描述符是唯一标识一个套接字的数字,它在程序中起到关键的作用。
对于开发人员来说,正确地分配和使用套接字描述符是确保网络通信稳定和高效的重要一环。
本文将深入探讨socket套接字描述符的分配规则,并提供一些使用注意事项。
首先,我们将对socket套接字描述符的定义进行详细介绍,以便读者对其有一个清晰的认识。
接着,我们将重点讨论socket套接字描述符的分配规则,包括其分配的原则和流程。
此外,我们还将提供一些使用套接字描述符时需要注意的事项,以避免可能出现的错误和问题。
总之,了解并遵守socket套接字描述符的分配规则,能够更好地优化网络通信,提升系统的性能和稳定性。
本文的目的是向读者介绍socket 套接字描述符的重要性,强调合理分配socket套接字描述符的必要性,并提出进一步研究socket套接字描述符分配规则的建议。
通过对这些内容的深入了解,读者将能够更好地利用socket套接字描述符,并在实际网络应用中取得更好的效果。
1.2 文章结构文章结构是指将一篇长文按照一定的组织方式进行划分,使读者能够更加清晰地理解文章的内容和逻辑结构。
文章结构的设计直接影响到读者对文章的理解和阅读效果。
本文的结构分为引言、正文和结论三个部分。
引言部分主要包括概述、文章结构和目的三个方面。
概述部分介绍了本文要讨论的主题-socket套接字描述符,并简要介绍了它的意义和作用。
文章结构部分则对整篇文章的结构进行了总体的概述,让读者对文章的组织有一个清晰的认识。
目的部分明确了本文的写作目的,即探讨socket 套接字描述符的分配规则以及使用注意事项。
正文部分是重点部分,包括几个小节,主要介绍了socket套接字描述符的定义、分配规则以及使用注意事项。
socket5的实现--(RFC1928)Socket5协议中文文档

socket5的实现--(RFC1928)Socket5协议中⽂⽂档(RFC1928)Socket5协议中⽂⽂档1、socket5的介绍:利⽤⽹络防⽕墙可以将组织内部的⽹络结构从外部⽹络如INTERNET中有效地隔离,这种⽅法在许多⽹络系统中正变得流⾏起来。
这种防⽕墙系统通常以应⽤层⽹关的形式⼯作在两个⽹络之间,提供TELNET、FTP、SMTP等的接⼊。
随着越来越多的使全球信息查找更容易的复杂的应⽤层协议的出现,有必要提供⼀个通⽤框架来使这些协议安全透明地穿过防⽕墙。
⽽且在实际应⽤中还需要⼀种安全的认证⽅式⽤以穿越防⽕墙。
这个要求起源于两个组织的⽹络中客户/服务器关系的出现,这个关系需要得到控制并要求有安全的认证。
在这⼉所描述的协议框架是为了让使⽤TCP和UDP的客户/服务器应⽤程序更⽅便安全地使⽤⽹络防⽕墙所提供的服务所设计的。
这个协议从概念上来讲是介于应⽤层和传输层之间的"中介层(shim-layer)",因⽽不提供如传递ICMP信息之类由⽹络层⽹关的所提供的服务。
2、现有的协议:当前存在⼀个协议SOCKS 4,它为TELNET、FTP、HTTP、WAIS和GOPHER等基于TCP协议的客户/服务器程序提供了⼀个不安全的防⽕墙。
⽽这个新的协议扩展了SOCKS V4,以使其⽀持UDP、框架规定的安全认证⽅案、地址解析⽅案(addressing scheme)中所规定的域名和IPV6。
为了实现这个SOCKS协议,通常需要重新编译或者重新链接基于TCP的客户端应⽤程序以使⽤SOCKS库中相应的加密函数。
注意:除⾮特别注明,所有出现在数据包格式图中的⼗进制数字均以字节表⽰相应域的长度。
如果某域需要给定⼀个字节的值,⽤X'hh'来表⽰这个字节中的值。
如果某域中⽤到单词'Variable',这表⽰该域的长度是可变的,且该长度定义在⼀个和这个域相关联(1 – 2个字节)的域中,或⼀个数据类型域中。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
套接字选项这个话题在socket编程里,可能已经属于中高级话题了,之所以在一开始就把这个话题提上来讲,是因为我们的一个近阶段目标是能够把MY_PF_INET域的RAW协议走通,并在上面跑起一个ping程序,所以,按照ping程序的要求,接下来,我们必须实现套接字选项系统调用setsockopt在MY_PF_INET中RAW协议中的相关实现。
下面是该系统调用函数的原型:#includeint setsockopt( int socket, int level, int option_name,const void *option_value, size_t option_len);第一个参数socket是套接字描述符。
第二个参数level是被设置的选项的级别,如果想要在套接字级别上设置选项,就必须把level设置为SOL_SOCKET。
option_name指定准备设置的选项,option_name可以有哪些取值,这取决于level,以linux 2.6内核为例(在不同的平台上,这种关系可能会有不同),在套接字级别上(SOL_SOCKET),option_name可以有以下取值:SO_DEBUG,打开或关闭调试信息。
当option_value不等于0时,打开调试信息,否则,关闭调试信息。
它实际所做的工作是在sock->sk->sk_flag中置SOCK_DBG(第10)位,或清SOCK_DBG位。
SO_REUSEADDR,打开或关闭地址复用功能。
当option_value不等于0时,打开,否则,关闭。
它实际所做的工作是置sock->sk->sk_reuse 为1或0。
SO_DONTROUTE,打开或关闭路由查找功能。
当option_value不等于0时,打开,否则,关闭。
它实际所做的工作是在sock->sk->sk_flag 中置或清SOCK_LOCALROUTE位。
SO_BROADCAST,允许或禁止发送广播数据。
当option_value不等于0时,允许,否则,禁止。
它实际所做的工作是在sock->sk->sk_flag 中置或清SOCK_BROADCAST位。
SO_SNDBUF,设置发送缓冲区的大小。
发送缓冲区的大小是有上下限的,其上限为256 * (sizeof(struct sk_buff) + 256),下限为2048字节。
该操作将sock->sk->sk_sndbuf设置为val * 2,之所以要乘以2,是防止大数据量的发送,突然导致缓冲区溢出。
最后,该操作完成后,因为对发送缓冲的大小作了改变,要检查sleep队列,如果有进程正在等待写,将它们唤醒。
SO_RCVBUF,设置接收缓冲区的大小。
接收缓冲区大小的上下限分别是:256 * (sizeof(struct sk_buff) + 256)和256字节。
该操作将sock->sk->sk_rcvbuf设置为val * 2。
SO_KEEPALIVE,套接字保活。
如果协议是TCP,并且当前的套接字状态不是侦听(listen)或关闭(close),那么,当option_value 不是零时,启用TCP保活定时器,否则关闭保活定时器。
对于所有协议,该操作都会根据option_value置或清sock->sk->sk_flag中的SOCK_KEEPOPEN位。
SO_OOBINLINE,紧急数据放入普通数据流。
该操作根据option_value的值置或清sock->sk->sk_flag中的SOCK_URGINLINE位。
SO_NO_CHECK,打开或关闭校验和。
该操作根据option_value的值,设置sock->sk->sk_no_check。
SO_PRIORITY,设置在套接字发送的所有包的协议定义优先权。
Linux通过这一值来排列网络队列。
这个值在0到6之间(包括0和6),由option_value指定。
赋给sock->sk->sk_priority。
SO_LINGER,如果选择此选项, close或shutdown将等到所有套接字里排队的消息成功发送或到达延迟时间后>才会返回. 否则, 调用将立即返回。
该选项的参数(option_value)是一个linger结构:view plaincopy to clipboardprint?1. struct linger {2. int l_onoff; /* 延时状态(打开/关闭)*/3. int l_linger; /* 延时多长时间*/4. };struct linger { int l_onoff; /* 延时状态(打开/关闭)*/ int l_linger; /* 延时多长时间*/ };如果linger.l_onoff值为0(关闭),则清sock->sk->sk_flag中的SOCK_LINGER位;否则,置该位,并赋sk->sk_lingertime值为linger.l_linger。
SO_PASSCRED,允许或禁止SCM_CREDENTIALS 控制消息的接收。
该选项根据option_value的值,清或置sock->sk->sk_flag中的SOCK_PASSCRED位。
SO_TIMESTAMP,打开或关闭数据报中的时间戳接收。
该选项根据option_value的值,清或置sock->sk->sk_flag中的SOCK_RCVTSTAMP位,如果打开,则还需设sock->sk->sk_flag中的SOCK_TIMESTAMP位,同时,将全局变量netstamp_needed加1。
SO_RCVLOWAT,设置接收数据前的缓冲区内的最小字节数。
在Linux中,缓冲区内的最小字节数是固定的,为1。
即将sock->sk->sk_rcvlowat固定赋值为1。
SO_RCVTIMEO,设置接收超时时间。
该选项最终将接收超时时间赋给sock->sk->sk_rcvtimeo。
SO_SNDTIMEO,设置发送超时时间。
该选项最终将发送超时时间赋给sock->sk->sk_sndtimeo。
SO_BINDTODEVICE,将套接字绑定到一个特定的设备上。
该选项最终将设备赋给sock->sk->sk_bound_dev_if。
SO_ATTACH_FILTER和SO_DETACH_FILTER。
关于数据包过滤,它们最终会影响sk->sk_filter。
以上所介绍的都是在SOL_SOCKET层的一些套接字选项,如果超出这个范围,给出一些不在这一level的选项作为参数,最终会得到- ENOPROTOOPT的返回值。
但以上的分析仅限于这些选项对sock-sk的值的影响,这些选项真正如何发挥作用,我们的探索道路将漫漫其修远。
如果不在套接字级别上设置选项,即setsockopt系统调用的参数level不设为SOL_SOCKET,那么sys_setsockopt的实现会直接调用sock->ops->setsockopt。
对MY_PF_INET域的RAW协议来讲,sock->ops = myinet_sockraw_ops,而myinet_sockraw_ops.setsockopt = sock_common_setsockopt。
而sock_common_setsockopt直接调用sock->sk->sk_prot->setsockopt。
对于RAW协议来讲,即myraw_setsockopt。
下面关注myraw_setsockopt的实现。
对于RAW协议来讲,level还可以有两种取值:SOL_IP 和SOL_RAW。
myraw_setsockopt首先检查level是否为SOL_IP,如果是,调用myip_setsockopt 函数,该函数实现IP级别上的选项,否则,为SOL_RAW级别上的选项,SOL_RAW级别上只有一个选项,即ICMP_FILTER,在MY_IPPROTO_ICMP协议下有效。
它激活绑定到MY_IPPROTO_ICMP协议的一个用于myraw socket特殊的过滤器。
该值对每种ICMP消息都有一个位(掩码),可以把那种ICMP消息过滤掉,缺省时是不过滤ICMP消息。
对于ICMP_FILTER选项,myraw_setsockopt调用myraw_seticmpfilter函数,它把option_value 赋给sock->sk->filter,option_value是一个结构体:view plaincopy to clipboardprint?1. struct icmp_filter {2. __u32 data;3. };struct icmp_filter { __u32 data; };它是一个32位的位掩码。
关于该位掩码,我们目前知道的是最低位为回显应答的位掩码,由于目前我们的MY_PF_INET 域代码还没完善,我们在PF_INET域上进行测试,把下面的代码添加到一个ping程序中,ping程序就收不到来自服务器的回应包了:1. #include <sys/types.h>2. #include <sys/socket.h>3. #include <errno.h>4.5. #include <linux/in.h>6. #include <linux/icmp.h>7. int main()8. {9. struct icmp_filter filter;10. socklen_t size = sizeof( struct icmp_filter );11. int fd = socket( PF_INET, SOCK_RAW, IPPROTO_ICMP );12. if( fd < 0 )13. perror("error: ");14.15. getsockopt( fd, SOL_RAW, ICMP_FILTER, &filter, &size );16. printf("the filter: %x\n", filter.data );17.18. filter.data = 1;19. int err = setsockopt( fd, SOL_RAW, ICMP_FILTER, &filter, sizeof(struct icmp_filter) );20. if( err < 0 )21. perror("error: ");22.23. memset( &filter, 0, sizeof( struct icmp_filter ) );24. getsockopt( fd, SOL_RAW, ICMP_FILTER, &filter, &size );25. printf("new filter: %x\n", filter.data);26.27. close(fd);28. return 0;29. }#include <sys/types.h> #include <sys/socket.h> #include <errno.h> #include <linux/in.h> #include <linux/icmp.h> int main() { struct icmp_filter filter; socklen_t size = sizeof( struct icmp_filter ); int fd = socket( PF_INET, SOCK_RAW, IPPROTO_ICMP ); if( fd < 0 ) perror("error: "); getsockopt( fd, SOL_RAW, ICMP_FILTER, &filter, &size ); printf("the filter: %x\n", filter.data ); filter.data = 1; int err= setsockopt( fd, SOL_RAW, ICMP_FILTER, &filter, sizeof(struct icmp_filter) ); if( err < 0 ) perror("error: "); memset( &filter, 0, sizeof( struct icmp_filter ) ); getsockopt( fd, SOL_RAW, ICMP_FILTER, &filter, &size ); printf("new filter: %x\n", filter.data); close(fd); return 0; }继续讲关于myraw_setsockopt的实现,如果level是SOL_IP,则调用myip_setsockopt函数。