.\" 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