raw 中文man页面

系统
Raw sockets 使得用户端可以实现新的 IPv4 协议。 raw socket 设备接收或发送不含链接层报头的原始数据包。只有激活接口选项 IP_HDRINCL 时 IPv4 层才会在传输包中添加 IP 报头。而且当激活时,包中必须含有 IP 报头。包中含有 IP 报头才能被接收。

NAME

raw, SOCK_RAW - Linux IPv4 raw socket.

总 览

#include <sys/socket.h>
#include <netinet/in.h>
raw_socket = socket(PF_INET, SOCK_RAW, int protocol );

描 述

Raw sockets 使得用户端可以实现新的 IPv4 协议。 raw socket 设备接收或发送不含链接层报头的原始数据包。只有激活接口选项 IP_HDRINCL 时 IPv4 层才会在传输包中添加 IP 报头。而且当激活时,包中必须含有 IP 报头。包中含有 IP 报头才能被接收。

只有 user id 为 0 或具有 CAP_NET_RAW 能力才能打开 raw sockets.

所有匹配为此 raw socket 声明的协议号的包或错误都将被传送到该 socket.要察看许可的协议列表,请参考 RFC1700 给出的代号和 getprotobyname (3).

IPPROTO_RAW 意味着 IP_HDRINCL 处于激活状态,也意味着接收所有 IP 协议. 但是不允许传送。

IP_HDRINCL 会在传送时修改 IP 报头。
 
IP Checksum 总是写入。
 
Source Address 为 0 时写入。
 
Packet Id 为 0 时写入。
 
Total Length 总是写入。
 

如果指定了 IP_HDRINCL 且 IP 报头含有的目的地址不是 0,那么该 socket 的目的地址用于路由该包。如果指定了 MSG_DONTROUTE 则目的地址应指向某个本地接口。否则会进行路有表查找,但是网关路由会被忽略。如果未设定 IP_HDRINCL 则可通过 setsockopt (2) 在 raw socket 中设定 IP header 选项。参考 ip (7) 了解更多信息。

在 Linux 2.2 下可以用 IP socket 选项设置所有的 IP 报头域和选项. 这意味着通常只有新的协议或没有用户界面的协议需要 raw socket (就象 ICMP). 当收到一个包时,它首先被传给绑定到包协议的任何 raw socket 然后才传给其他协议句柄(handler)。 (比如.内核协议模块).

地址格式

raw socket 使用在 ip (7) 中定义的标准 sockaddr_in 地址结构。 sin_port 域用于指定 IP 协议号,但是在 Linux 2.2 下传送时应将其忽略,而且应该一直设为0 (参见 BUGS).

对于接收的包,sin_port 被设置为该包的协议号。参考 其中包括介绍有效的 IP 协议的文件.

SOCKET选项

raw socket 选项可使用 setsockopt (2) 进行设置,用 getsockopt (2)进行读取(通过传递 SOL_RAW 族标志).

ICMP_FILTER
激活绑定到 IPPROTO_ICMP 协议的一个用于 raw socket 特殊的过滤器。该值对每种 ICMP 消息都有一个位(掩码),可以把那种 ICMP 消息过滤掉.缺省时是不过滤 ICMP 消息.

另外,还支持所有对数据报 socket 有效的 ip(7) SOL_IP socket 选项.

注 意

raw socket 包长超过接口 MTU 时会把包分成碎片。(另见 BUGS). 另一个更友好和快速的选择是使用路径 MTU 查找。 在 ip (7) IP_PMTU_DISCOVER 一段有详细描述。

使用 bind (2) 可将 raw socket 绑定到指定的本地地址。如果没有绑定,则接收所有符合指定的 IP 协议的包。另外用 SO_BINDTODEVICE 可以将 RAW socket 绑定到指定的网络设备。 详见: socket (7).

IPPROTO_RAW 只能传送。如果你确实想接收所有的 IP 包用 packet (7) socket 和 ETH_P_IP 协议. 请注意 packet socket不象 raw socket 那样对 IP 碎片进行重组。

如果想要为一个 datagram socket 接收的所有 ICMP 包,那么最好在那个 socket 上使用 IP_RECVERR。详见: ip (7).

raw socket 能窃听所有的 IP 协议, 即使象 ICMP 或 TCP 这样在内核中有协议模块的也不例外。这时候包会同时传送到核心模块和raw socket. 一个可移植的程序不能依赖这个特性,许多其他 BSD socket 实现在这方面有局限.

Linux 从不改变用户传输的包 (除了前面提到的 IP_HDRINCL ,填入一些0字段).这与其他 raw socket 实现方式是不同的.

RAW socket 通常很难移植. socket 传输时使用 sin_port 中设置的协议,但 Linux2.2 下不行了,解决办法是使用 IP_HDRINCL.

错误处理

只有连接了 socket 或 IP_RECVERR 设置为有效时,网络错误才会传送给用户。因为兼容性的原因只有 EMSGSIZE 和 EPROTO 被传送给 socket.

错 误

IP_RECVERR
使得所有的错误存储到 error queue(错误队列).
EMSGSIZE
包太大。或者因为路径 MTU 查找 (IP_PMTU_DISCOVER)设置为有效,或者因为包的尺寸超过 IPv4 规定的包最大尺寸 64KB.
EACCES
用户试图传送到某广播地址但是并未事先在socket中设置广播标志。
EPROTO
ICMP 错误报告有参数问题。
EFAULT
无效内存地址。
EOPNOTSUPP
传送给 socket 的标志无效(比如:MSG_OOB ).
EINVAL
无效参数.
EPERM
用户无权打开 raw socket. 只有用户 id 为 0 或具有 CAP_NET_RAW 属性方可。

版 本

IP_RECVERR 和 ICMP_FILTER 是 Linux 2.2 的新实现. 不能用于可移植程序。

如果设置了 SO_BSDCOMPAT 标志, Linux 2.0 里面有和 BSD 里兼容的 raw socket 代码错误,在 2.2 里已经修补了.

BUGS

没有描述透明代理扩展.

当设置 IP_HDRINCL 选项后datagrams(自寻址数据包)不会被分段并受 MTU 限制. 这是 Linux 2.2 的限制.

在 Linux 2.2 sin_port 中设置的 IP 协议会丢失。使用的是绑定了 socket 的协议,或在 socket (2)初始化调用中指定的协议。

作 者

Andi Kleen.  

另 见

ip(7), socket(7), recvmsg(2), sendmsg(2).

RFC1191 for path MTU discovery.
RFC791 and the include file for the IP protocol.
#p#

NAME

raw, SOCK_RAW - Linux IPv4 raw sockets  

SYNOPSIS

#include <sys/socket.h>
#include <netinet/in.h>
raw_socket = socket(PF_INET, SOCK_RAW, int protocol);

DESCRIPTION

Raw sockets allow new IPv4 protocols to be implemented in user space. A raw socket receives or sends the raw datagram not including link level headers.

The IPv4 layer generates an IP header when sending a packet unless the IP_HDRINCL socket option is enabled on the socket. When it is enabled, the packet must contain an IP header. For receiving the IP header is always included in the packet.

Only processes with an effective user id of 0 or the CAP_NET_RAW capability are allowed to open raw sockets.

All packets or errors matching the protocol number specified for the raw socket are passed to this socket. For a list of the allowed protocols see RFC1700 assigned numbers and getprotobyname(3).

A protocol of IPPROTO_RAW implies enabled IP_HDRINCL and is able to send any IP protocol that is specified in the passed header. Receiving of all IP protocols via IPPROTO_RAW is not possible using raw sockets.

IP Header fields modified on sending by IP_HDRINCL
 
IP Checksum Always filled in.
 
Source Address Filled in when zero.
 
Packet Id Filled in when zero.
 
Total Length Always filled in.
 

If IP_HDRINCL is specified and the IP header has a non-zero destination address then the destination address of the socket is used to route the packet. When MSG_DONTROUTE is specified the destination address should refer to a local interface, otherwise a routing table lookup is done anyways but gatewayed routes are ignored.

If IP_HDRINCL isn't set then IP header options can be set on raw sockets with setsockopt(2); see ip(7) for more information.

In Linux 2.2 all IP header fields and options can be set using IP socket options. This means raw sockets are usually only needed for new protocols or protocols with no user interface (like ICMP).

When a packet is received, it is passed to any raw sockets which have been bound to its protocol before it is passed to other protocol handlers (e.g. kernel protocol modules).

ADDRESS FORMAT

Raw sockets use the standard sockaddr_in address structure defined in ip(7). The The sin_port field could be used to specify the IP protocol number, but it is ignored for sending in Linux 2.2 and should be always set to 0 (see BUGS) For incoming packets sin_port is set to the protocol of the packet. See the <netinet/in.h> include file for valid IP protocols.

SOCKET OPTIONS

Raw socket options can be set with setsockopt(2) and read with getsockopt(2) by passing the SOL_RAW family flag.

ICMP_FILTER
Enable a special filter for raw sockets bound to the IPPROTO_ICMP protocol. The value has a bit set for each ICMP message type which should be filtered out. The default is to filter no ICMP messages.

In addition all ip(7) SOL_IP socket options valid for datagram sockets are supported.

NOTES

Raw sockets fragment a packet when its total length exceeds the interface MTU (but see BUGS). A more network friendly and faster alternative is to implement path MTU discovery as described in the IP_MTU_DISCOVER section of ip(7).

A raw socket can be bound to a specific local address using the bind(2) call. If it isn't bound all packets with the specified IP protocol are received. In addition a RAW socket can be bound to a specific network device using SO_BINDTODEVICE; see socket(7).

An IPPROTO_RAW socket is send only. If you really want to receive all IP packets use a packet(7) socket with the ETH_P_IP protocol. Note that packet sockets don't reassemble IP fragments, unlike raw sockets.

If you want to receive all ICMP packets for a datagram socket it is often better to use IP_RECVERR on that particular socket; see ip(7).

Raw sockets may tap all IP protocols in Linux, even protocols like ICMP or TCP which have a protocol module in the kernel. In this case the packets are passed to both the kernel module and the raw socket(s). This should not be relied upon in portable programs, many other BSD socket implementation have limitations here.

Linux never changes headers passed from the user (except for filling in some zeroed fields as described for IP_HDRINCL). This differs from many other implementations of raw sockets.

RAW sockets are generally rather unportable and should be avoided in programs intended to be portable.

Sending on raw sockets should take the IP protocol from sin_port; this ability was lost in Linux 2.2. Work around is to use IP_HDRINCL.

ERROR HANDLING

Errors originating from the network are only passed to the user when the socket is connected or the IP_RECVERR flag is enabled. For connected sockets only EMSGSIZE and EPROTO are passed for compatibility. With IP_RECVERR all network errors are saved in the error queue.  

ERRORS

EMSGSIZE
Packet too big. Either Path MTU Discovery is enabled (the IP_MTU_DISCOVER socket flag) or the packet size exceeds the maximum allowed IPv4 packet size of 64KB.
EACCES
User tried to send to a broadcast address without having the broadcast flag set on the socket.
EPROTO
An ICMP error has arrived reporting a parameter problem.
EFAULT
An invalid memory address was supplied.
EOPNOTSUPP
Invalid flag has been passed to a socket call (like MSG_OOB).
EINVAL
Invalid argument.
EPERM
The user doesn't have permission to open raw sockets. Only processes with a effective user id of 0 or the CAP_NET_RAW attribute may do that.

VERSIONS

IP_RECVERR and ICMP_FILTER are new in Linux 2.2. They are Linux extensions and should not be used in portable programs.

Linux 2.0 enabled some bug-to-bug compatibility with BSD in the raw socket code when the SO_BSDCOMPAT flag was set - that has been removed in 2.2.

BUGS

Transparent proxy extensions are not described.

When the IP_HDRINCL option is set datagrams will not be fragmented and are limited to the interface MTU. This is a limitation in Linux 2.2.

Setting the IP protocol for sending in sin_port got lost in Linux 2.2. The protocol that socket was bound to or that was specified in the initial socket(2) call is always used.

AUTHORS

This man page was written by Andi Kleen.

SEE ALSO

ip(7), socket(7), recvmsg(2), sendmsg(2)

RFC1191 for path MTU discovery.

RFC791 and the <linux/ip.h> include file for the IP protocol.

责任编辑:韩亚珊 来源: CMPP.net
相关推荐

2011-08-24 16:48:36

man中文man

2011-08-15 10:21:09

man中文man

2011-08-11 16:11:49

at中文man

2011-08-25 10:21:56

man.conf中文man

2011-08-12 14:58:05

killall中文man

2011-07-15 16:58:36

ac中文man

2011-08-15 11:10:48

more中文man

2011-08-25 17:03:51

pclose中文man

2011-08-15 14:10:37

tar中文man

2011-08-16 10:42:30

rmmod中文man

2011-08-18 13:57:38

acct中文man

2011-08-23 17:49:36

zdump中文man

2011-08-15 15:10:49

wall中文man

2011-08-23 15:06:03

quotastats中文man

2011-08-15 17:35:50

ar中文man

2011-08-25 09:07:16

suffixes中文man

2011-08-18 15:21:37

autofs中文man

2011-08-25 15:19:39

dirname中文man

2011-08-25 17:34:50

setlinebuf中文man

2011-08-15 15:17:14

ac中文man
点赞
收藏

51CTO技术栈公众号