Provided by: manpages-zh_1.5.2-1_all bug

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.

[ä¸ä¸­æ–æ–‡ç‰ç‰ˆç»ç»´æŠæŠ¤äºäºº]
       RedCandle <redcandle51@chinaren.com>

[ä¸ä¸­æ–æ–‡ç‰ç‰ˆæœæœ€æ–æ–°æ›æ›´æ–æ–°]
       2000/10/15

ã€ã€Šä¸ä¸­å›å›½linuxè®è®ºåå›manæ‰æ‰‹å†å†Œé¡é¡µç¿ç¿»è¯è¯‘è®è®¡åˆåˆ’ã€ã€‹:
       http://cmpp.linuxforum.net