.\" Don't change the first line, it tells man that we need tbl. .\" This man page is Copyright (C) 1999 Andi Kleen . .\" 中文版版權所有 redcandle, Laser www.linuxforum.net 2000 .\" Permission is granted to distribute possibly modified copies .\" of this page provided the header is included verbatim, .\" and in case of nontrivial modification author and date .\" of the modification is added to the header. .\" Please send bug reports, corrections and suggestions for improvements to .\" .TH RAW 7 "2 Oct 1998" "Linux 手冊頁" "Linux 程序員手冊" .SH NAME raw, SOCK_RAW \- Linux IPv4 raw socket. .SH 總 覽 #include .br #include .br raw_socket = socket(PF_INET, SOCK_RAW, int protocol ); .SH 描 述 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 協議. 但是不允許傳送。 .TS tab(:) allbox; c s l l. IP_HDRINCL 會在傳送時修改 IP 報頭。 IP Checksum: 總是寫入。 Source Address:爲 0 時寫入。 Packet Id:爲 0 時寫入。 Total Length:總是寫入。 .TE .PP 如果指定了 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)。 (比如.內核協議模塊). .SH 地址格式 raw socket 使用在 ip (7) 中定義的標準 sockaddr_in 地址結構。 sin_port 域用於指定 IP 協議號,但是在 Linux 2.2 下傳送時應將 其忽略,而且應該一直設爲0 (參見 BUGS). 對於接收的包,sin_port 被設置爲該包的協議號。 參考 其中包括介紹有效的 IP 協議的文件. .SH SOCKET選項 raw socket 選項可使用 setsockopt (2) 進行設置,用 getsockopt (2)進行讀取(通過傳遞 SOL_RAW 族標誌). .TP .B ICMP_FILTER 激活綁定到 IPPROTO_ICMP 協議的一個用於 raw socket 特殊的過濾器。 該值對每種 ICMP 消息都有一個位(掩碼), 可以把那種 ICMP 消息過濾掉.缺省時是不過濾 ICMP 消息. 另外,還支持所有對數據報 socket 有效的 ip(7) SOL_IP socket 選項. .SH 注 意 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. .SH 錯誤處理 只有連接了 socket 或 IP_RECVERR 設置爲有效時,網絡錯誤纔會 傳送給用戶。因爲兼容性的原因只有 EMSGSIZE 和 EPROTO 被傳送 給 socket. .SH 錯 誤 .TP .B IP_RECVERR 使得所有的錯誤存儲到 error queue(錯誤隊列). .TP .B EMSGSIZE 包太大。或者因爲路徑 MTU 查找 (IP_PMTU_DISCOVER) 設置爲有效,或者因爲包的尺寸超過 IPv4 規定的包 最大尺寸 64KB. .TP .B EACCES 用戶試圖傳送到某廣播地址但是並未事先在socket中設置廣播 標誌。 .TP .B EPROTO ICMP 錯誤報告有參數問題。 .TP .B EFAULT 無效內存地址。 .TP .B EOPNOTSUPP 傳送給 socket 的標誌無效(比如:MSG_OOB ). .TP .B EINVAL 無效參數. .TP .B EPERM 用戶無權打開 raw socket. 只有用戶 id 爲 0 或具有 CAP_NET_RAW 屬性方可。 .SH 版 本 IP_RECVERR 和 ICMP_FILTER 是 Linux 2.2 的新實現. 不能用於可移植程序。 如果設置了 SO_BSDCOMPAT 標誌, Linux 2.0 裏面有和 BSD 裏兼容的 raw socket 代碼錯誤, 在 2.2 裏已經修補了. .SH BUGS 沒有描述透明代理擴展. 當設置 IP_HDRINCL 選項後datagrams(自尋址數據包)不會被分段 並受 MTU 限制. 這是 Linux 2.2 的限制. 在 Linux 2.2 sin_port 中設置的 IP 協議會丟失。使用的是綁定了 socket 的協議,或在 socket (2)初始化調用中指定的協議。 .SH 作 者 Andi Kleen. .SH 另 見 .BR ip (7), .BR socket (7), .BR recvmsg (2), .BR sendmsg (2). .PP RFC1191 for path MTU discovery. .br RFC791 and the include file for the IP protocol. .br .SH "[中文版維護人]" .B RedCandle .SH "[中文版最新更新]" .B 2000/10/15 .SH "《中國linux論壇man手冊頁翻譯計劃》:" .BI http://cmpp.linuxforum.net .SH "跋" .br 本頁面中文版由中文 man 手冊頁計劃提供。 .br 中文 man 手冊頁計劃:\fBhttps://github.com/man-pages-zh/manpages-zh\fR