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

NAME (名稱)

       ip - Linux IPv4 協議實現

SYNOPSIS(總覽)

       #include <sys/socket.h>
       #include <net/netinet.h>

       tcp_socket = socket(PF_INET, SOCK_STREAM, 0);
       raw_socket = socket(PF_INET, SOCK_RAW, protocol);
       udp_socket = socket(PF_INET, SOCK_DGRAM, protocol);

DESCRIPTION(描述)

       Linux 實現描述於 RFC791 和 RFC1122 中的 Internet 協議,版本4.  ip 包括遵循 RFC1112 的第二層
       的多信道廣播技術的實現.它也包括含包過濾器的IP路由器.

       程式員的接口與 BSD 的套接字(socket)相容. 要獲得關於套接字的更多信息,參見 socket(7)

       創建一個IP套接字是通過以 socket(PF_INET, socket_type, protocol) 方式調用 socket(2)  函數來
       實現的.  有效的套接字類型(socket_type)有:  SOCK_STREAM  用來打開一個  tcp(7)  套接字,
       SOCK_DGRAM 用來打開一個 udp(7) 套接字,或者是 SOCK_RAW 用來打開一個 raw(7)  套接字用來直接
       訪問  IP  協議. protocol 指的是要接收或者發送出去的包含在 IP 頭標識(header)中的 IP 協議.
       對於TCP套接字而言,唯一的有效 protocol 值是 0IPPROTO_TCP  對於UDP套接字而言,唯一的有效
       protocol  值是  0IPPROTO_UDP.  而對於 SOCK_RAW 你可以指定一個在 RFC1700 中定義的有效
       IANA IP 協議代碼來賦值.

       當一個進程希望接受新的來訪包或者連接時,它應該使用  bind(2)  綁定一個套接字到一個本地接口地
       址.  任意給定的本地(地址,端口)對只能綁定一個IP套接字.  當調用 bind 時中聲明了 INADDR_ANY
       時,套接字將會綁定到  所有  本地接口.當在未綁定的套接字上調用  listen(2)  或者  connect(2)
       時,套接字會自動綁定到一個本地地址設置為 INADDR_ANY 的隨機的空閒端口上.

       除非你設置了  S0_REUSEADDR 標識,否則一個已綁定的 TCP 本地套接字地址在關閉後的一段時間內不
       可用. 使用該標識的時候要小心,因為它會使 TCP 變得不可靠.

ADDRESS FORMAT(地址格式)

       一個 IP 套接字地址定義為一個 IP 接口地址和一個端口號的組合. 基本 IP 協議不會提供端口號,它
       們通過更高層次的協議如 udp(7) 和 tcp(7) 來實現. 對於raw套接字, sin_port 設置為IP協議.

              struct sockaddr_in {
              sa_family_t sin_family; /* 地址族: AF_INET */
              u_int16_t sin_port; /* 按網路字節次序的端口 */
              struct in_addr sin_addr; /* internet地址 */
              };

              /* Internet地址. */
              struct in_addr {
              u_int32_t s_addr; /* 按網路字節次序的地址 */
              };

       sin_family  總是設置為 AF_INET.  這是必需的;在 Linux 2.2 中,如果該設置缺失,大多數聯網函
       數會返回 EINVAL sin_port 包含按網路字節排序的端口號.端口號在1024以下的稱為 保留端口.  只
       有那些有效使用者標識為  0  或者 CAP_NET_BIND_SERVICE 有功能的進程才可以 bind(2) 到這些套接
       字.注意原始的(raw)IPv4協議沒有這樣的端口概念,它們只通過更高的協議如 tcp(7) 和 udp(7) 來
       實現.

       sin_addr 指的是 IP 主機地址.  在 struct in_addr 中的 addr 部分包含按網路字節序的主機接口地
       址. in_addr 應該只能通過使用 inet_aton(3), inet_addr(3), inet_makeaddr(3)  庫函數或者直接
       通過名字解析器(參見 gethostbyname(3)) 來訪問. IPv4 地址分成單點廣播,廣播傳送和多點廣播
       地址. 單點廣播地址指定了一台主機的單一接口,廣播地址指 定了在一個網段上的所有主機,  而多
       點廣播地址則在一個多點傳送組中尋址所有主機.  只有當設置了套接字標識 SO_BROADCAST 時, 才能
       收發數據報到廣播地址. 在當前的實現中,面向連接的套接字只允許使用單點傳送地址.

       注意地址和端口總是按照網路字節序存儲的.  這意味著你需要對分配給端口的號碼調用  htons(3)
       所有在標準庫中的地址/端口處理函數都是按網路字節序運行的.

       有幾個特殊的地址: INADDR_LOOPBACK (127.0.0.1) 總是代表經由回環設備的本地主機; INADDR_ANY
       (0.0.0.0) 表示任何可綁定的地址; INADDR_BROADCAST (255.255.255.255) 表示任何主機,由於歷史
       的原因,這與綁定為 INADDR_ANY 有同樣的效果.

SOCKET OPTIONS(套接字選項)

       IP    支持一些與協議相關的套接字選項,這些選項可以通過    setsockopt(2)   設置,並可以通過
       getsockopt(2) 讀取. IP 的套接字選項級別為 SOL_IP  這是一個布爾整型標識,當值為0時為假,否則
       則為真.

       IP_OPTIONS
              設置或者獲取將由該套接字發送的每個包的 IP 選項. 該參數是一個指向包含選項和選項長度
              的存儲緩沖區的指針. setsockopt(2) 系統調用設置與一個套接字相關聯的 IP 選項.   IPv4
              的最大選項長度為 40 字節. 參閱 RFC791 獲取可用的選項. 如果一個 SOCK_STREAM 套接字
              收到的初始連接請求包包含 IP 選項時, IP  選項自動設置為來自初始包的選項,同時反轉路
              由頭.  在連接建立以後將不允許來訪的包修改選項. 預設情況下是關閉對所有來訪包的源路
              由選項的,你可以用  accept_source_route   sysctl   來激活.仍然處理其它選項如時間戳
              (timestamp).      對於數據報套接字而言,IP      選項只能由本地使用者設置.調用帶
              IP_OPTIONSgetsockopt(2) 會把當前用於發送的 IP 選項放到你提供的緩沖區中.

       IP_PKTINFO
              傳遞一條包含 pktinfo  結構(該結構提供一些來訪包的相關信息)的  IP_PKTINFO  輔助信息.
              這個選項只對數據報類的套接字有效.

              struct in_pktinfo
              {
              unsigned int ipi_ifindex; /* 接口索引 */
              struct in_addr ipi_spec_dst; /* 路由目的地址 */
              struct in_addr ipi_addr; /* 頭標識目的地址 */
              };

              ipi_ifindex  指的是接收包的接口的唯一索引. ipi_spec_dst 指的是路由表記錄中的目的地
              址,而 ipi_addr 指的是包頭中的目的地址. 如果給 sendmsg (2)傳遞了 IP_PKTINFO, 那麼
              外發的包會通過在  ipi_ifindex 中指定的接口 發送出去,同時把 ipi_spec_dst 設置為目的
              地址.

       IP_RECVTOS
              如果打開了這個選項,則 IP_TOS , 輔助信息會與來訪包一起傳遞. 它包含一個字節用來指定
              包頭中的服務/優先級字段的類型. 該字節為一個布爾整型標識.

       IP_RECVTTL
              當設置了該標識時, 傳送一條帶有用一個字節表示的接收包生存時間(time to live)字段的
              IP_RECVTTL 控制信息. 此選項還不支持 SOCK_STREAM 套接字.

       IP_RECVOPTS
              用一條 IP_OPTIONS 控制信息傳遞所有來訪的 IP 選項給使用者. 路由頭標識和其它選項已經
              為本地主機填好. 此選項還不支持 SOCK_STREAM 套接字.

       IP_RETOPTS
              等同於 IP_RECVOPTS 但是返回的是帶有時間戳的未處理的原始選項和在這段路由中未填入的路
              由記錄項目.

       IP_TOS 設置或者接收源於該套接字的每個IP包的 Type-Of-Service (TOS 服務類型)字段.它被用來
              在網路上區分包的優先級.    TOS    是單字節的字段.定義了一些的標準    TOS   標識:
              IPTOS_LOWDELAY 用來為交互式通信最小化延遲時間,  IPTOS_THROUGHPUT  用來優化吞吐量,
              IPTOS_RELIABILITY 用來作可靠性優化, IPTOS_MINCOST 應該被用作"填充數據",對於這些數
              據,低速傳輸是無關緊要的. 至多只能聲明這些 TOS  值中的一個.其它的都是無效的,應當
              被清除. 預設時,Linux首先發送 IPTOS_LOWDELAY 數據報, 但是確切的做法要看配置的排隊規
              則而定.  一些高優先級的層次可能會要求一個有效的使用者標識 0 或者  CAP_NET_ADMIN  能
              力.   優先級也可以以於協議無關的方式通過(  SOL_SOCKET, SO_PRIORITY )套接字選項(參看
              socket(7) )來設置.

       IP_TTL 設置或者檢索從此套接字發出的包的當前生存時間字段.

       IP_HDRINCL
              如果打開的話, 那麼使用者可在使用者數據前面提供一個 ip 頭.  這只對 SOCK_RAW  有效.參
              看 raw(7) 以獲得更多信息.當激活了該標識之後,其值由 IP_OPTIONS 設定,並且 IP_TOS 被忽
              略.

       IP_RECVERR
              允許傳遞擴展的可靠的錯誤訊息.  如果在數據報上激活了該標識, 那麼所有產生的錯誤會在每
              套接字一個的錯誤隊列中排隊等待.   當使用者從套接字操作中收到錯誤時,就可以通過調用設
              置了 MSG_ERRQUEUE 標識的 recvmsg(2) 來接收.  描述錯誤的 sock_extended_err  結構將通
              過一條類型為  IP_RECVERR , 級別為 SOL_IP的輔助信息進行傳遞.  這個選項對在未連接的套
              接字上可靠地處理錯誤很有用.  錯誤隊列的已收到的數據部分包含錯誤包.

              IP 按照下面的方法使用 sock_extended_err 結構:  ICMP  包接收的錯誤  ee_origin  設為
              SO_EE_ORIGIN_ICMP  ,  對於本地產生的錯誤則設為  SO_EE_ORIGIN_LOCAL  .   ee_typeee_code 設置為 ICMP 頭標識的類型和代碼字段.   ee_info  包含用於  EMSGSIZE  時找到的
              MTU.     ee_data   目前沒有使用.    當錯誤來自於網路時,該套接字上所有IP選項都被激活
              (IP_OPTIONS, IP_TTL, 等.)並且當做控制信息包含錯誤包中傳遞.引發錯誤的包的有效載荷會
              以正常數據返回.

              在 SOCK_STREAM 套接字上, IP_RECVERR 會有細微的語義不同.它並不保存下次超時的錯誤,而
              是立即傳遞所有進來的錯誤給使用者.  這對 TCP 連接時間很短的情況很有用,因為它要求快速
              的錯誤處理.    使用該選項要小心:因為不允許從路由轉移和其它正   常條件下正確地進行恢
              復,它使得TCP變得不可靠,並且破壞協議的規範.  注意TCP沒有錯誤隊列; MSG_ERRQUEUE  對於
              SOCK_STREAM 套接字是非法的.  因此所有錯誤都會由套接字函數返回,或者只返回 SO_ERROR .

              對於原始(raw)套接字而言, IP_RECVERR 允許傳遞所有接收到的ICMP錯誤給應用程式,否則錯誤
              只在連接的套接字上報告出來.

              它設置或者檢索一個整型布爾標識.  IP_RECVERR 預設設置為off(關閉).

       IP_PMTU_DISCOVER
              為套接字設置或接收Path MTU Discovery setting(路徑MTU發現設置).   當允許時,Linux會在
              該套接字上執行定  義於RFC1191中的Path MTU Discovery(路徑MTU發現).  don't 段標識會設
              置在所有外發的數據報上.     系統級別的預設值是這樣的:     SOCK_STREAM     套接字由
              ip_no_pmtu_disc sysctl 控制,而對其它所有的套接字都被都屏蔽掉了,對於非 SOCK_STREAM
              套接字而言,  使用者有責任按照MTU的大小對數據分塊並在必要的情況下進行中繼重發.如果設
              置了該標識 (用 EMSGSIZE ),核心會拒絕比已知路徑MTU更大的包.

              Path MTU discovery(路徑MTU發現)標識   含義
              IP_PMTUDISC_WANT                      對每條路徑進行設置.
              IP_PMTUDISC_DONT                      從不作Path MTU Discovery(路徑MTU發現).
              IP_PMTUDISC_DO                        總作Path MTU Discovery(路徑MTU發現).

              當允許 PMTU (路徑MTU)搜索時, 核心會自動記錄每個目的主機的path MTU(路徑MTU).當它使
              用 connect(2) 連接到一個指定的對端機器時,可以方便地使用 IP_MTU 套接字選項檢索當前已
              知的 path MTU(路徑MTU)(比如,在發生了一個 EMSGSIZE 錯誤後).它可能隨著時間的推移而改
              變.  對於帶有許多目的端的非連接的套接字,一個特定目的端的新到來的 MTU 也可以使用錯誤
              隊列(參看 IP_RECVERR) 來存取訪問.  新的錯誤會為每次到來的 MTU 的更新排隊等待.

              當進行  MTU 搜索時,來自數據報套接字的初始包可能會被丟棄.  使用 UDP 的應用程式應該知
              道這個並且考慮 其包的中繼傳送策略.

              為了在未連接的套接字上引導路徑  MTU   發現進程,   我們可以用一個大的數據報(頭尺寸超
              過64K字節)啟動, 並令其通過更新路徑 MTU 逐步收縮.

              為了獲得路徑MTU連接的初始估計,可通過使用  connect(2) 把一個數據報套接字連接到目的地
              址,並通過調用帶 IP_MTU選項的 getsockopt(2) 檢索該MTU.

       IP_MTU 檢索當前套接字的當前已知路徑MTU.只有在套接字被連接時才是有效的.返回一個整數.只有作
              為一個 getsockopt(2) 才有效.

       IP_ROUTER_ALERT
              給該套接字所有將要轉發的包設置IP路由器警告(IP  RouterAlert option)選項.  只對原始
              套接字(raw socket)有效,這對使用者空間的 RSVP後 台守護程式之類很有用.   分解的包不
              能被核心轉發,使用者有責任轉發它們.套接字綁定被忽略, 這些包只按協議過濾.  要求獲得一
              個整型標識.

       IP_MULTICAST_TTL
              設置或者讀取該套接字的外發多點廣播包的生存時間值.      這對於多點廣播包設置可能的最
              小TTL很重要.   預設值為1,這意味著多點廣播包不會超出本地網段, 除非使用者程式明確地要
              求這麼做.參數是一個整數.

       IP_MULTICAST_LOOP
              設置或讀取一個布爾整型參數以決定發送的多點廣播包是否應該被回送到本地套接字.

       IP_ADD_MEMBERSHIP
              加入一個多點廣播組.參數為 struct ip_mreqn 結構.

              struct ip_mreqn
              {
              struct in_addr imr_multiaddr; /* IP多點傳送組地址 */
              struct in_addr imr_address; /* 本地接口的IP地址 */
              int imr_ifindex; /* 接口索引 */
              };

              imr_multiaddr 包含應用程式希望加入或者退出的多點廣播組的地址.  它必須是一個有效的多
              點廣播地址.      imr_address    指的是系統用來加入多點廣播組的本地接口地址;如果它與
              INADDR_ANY   一致,那麼由系統選擇一個合適的接口.    imr_ifindex    指的是要加入/脫離
              imr_multiaddr 組的接口索引,或者設為0表示任何接口.

              由於相容性的緣故,老的  ip_mreq 接口仍然被支持.它與 ip_mreqn 只有一個地方不同,就是沒
              有包括 imr_ifindex 字段.這只在作為一個 setsockopt(2) 時才有效.

       IP_DROP_MEMBERSHIP
              脫離一個多點廣播組.參數為 ip_mreqn 或者 ip_mreq 結構,這與 IP_ADD_MEMBERSHIP 類似.

       IP_MULTICAST_IF
              為多點廣播套接字設置本地設備.參數為     ip_mreqn     或者     ip_mreq     結構,它與
              IP_ADD_MEMBERSHIP 類似.

              當傳遞一個無效的套接字選項時,返回 ENOPROTOOPT .

SYSCTLS

       IP協議支持  sysctl 接口配置一些全局選項.sysctl可通過讀取或者寫入 /proc/sys/net/ipv4/* 檔案
       或使用 sysctl(2) 接口來存取訪問.

       ip_default_ttl
              設置外發包的預設生存時間值.此值可以對每個套接字通過 IP_TTL 選項來修改.

       ip_forward
              以一個布爾標識來激活IP轉發功能.IP轉發也可以按接口來設置

       ip_dynaddr
              打開接口地址改變時動態套接字地址和偽裝記錄的重寫.  這對具有變化的IP地址的撥號接口很
              有 用.0表示不重寫,1打開其功能,而2則激活冗餘模式.

       ip_autoconfig
              無文件

       ip_local_port_range
              包含兩個整數,定義了預設分配給套接字的本地端口范圍.   分配起始於第一個數而終止於第二
              個數.  注意這些端口不能與偽裝所使用的端口相沖突(儘管這種情況也可以處理).  同時,隨意
              的選擇可能會導致一些防火牆包過濾器的問題,它們會誤認為本地端口在使用.   第一個數必須
              至少>1024,最好是>4096以避免與眾所周知的端口發生沖突, 從而最大可能的減少防火牆問題.

       ip_no_pmtu_disc
              如果打開了,預設情況下不對TCP套接字執行路徑MTU發現.  如果在路徑上誤配置了防火牆(用來
              丟棄所有 ICMP包)或者誤配置了接口 (例如,設置了一個兩端MTU不同的端對端連接),路徑MTU發
              現可能會失敗.  寧願修復路徑上的損壞的路由器,也好過整個地關閉路徑MTU發現, 因為這樣做
              會導致網路上的高開銷.

       ipfrag_high_thresh, ipfrag_low_thresh
              如果排隊等待的IP碎片的數目達到  ipfrag_high_thresh , 隊列被排空為 ipfrag_low_thresh
              .  這包含一個表示字節數的整數.

       ip_always_defrag
              [kernel                        2.2.13中的新功能;在早期核心版本中,該功能在編譯時通過
              CONFIG_IP_ALWAYS_DEFRAG 選項來控制]

              當該布爾標識被激活(不等於0)時, 來訪的碎片(IP包的一部分,這生成於當一些在源端和目的端
              之間的主機認 定包太大而分割成許多碎片的情況下)將在處理之前重新組合(碎片整理),  即使
              它們馬上要被轉發也如此.

              只在運行著一台與網路單一連接的防火牆或者透明代理伺服器時才這麼幹;  對於正常的路由器
              或者主機, 永遠不要打開它.  否則當碎片在不同連接中通過時碎片的通信可能會被擾亂.   而
              且碎片重組也需要花費大量的記憶體和 CPU 時間.

              這在配置了偽裝或者透明代理的情況下自動打開.

       neigh/*
              參看 arp(7)

IOCTLS

       所有在 socket(7) 中有描述 的 ioctl 都可應用於ip.

       用於配置防火牆應用的ioctl記載在 ipchains 包的 ipfw(7) 的文件中.

       用來配置普通設備參數的ioctl在 netdevice(7) 中有描述.

NOTES(備注)

       使用  SO_BROADCAST  選項要小心  - 它在 Linux 中沒有權限要求.  不小心的廣播很容易導致網路過
       載.對於新的應用協議而言,最 好是使用多點廣播組來替代廣播.我們不鼓勵使用廣播.

       有些其它的BSD套接字實現提供了 IP_RCVDSTADDRIP_RECVIF  套接字選項來獲得目的地址以及接收
       數據報的接口.Linux有更通用的 IP_PKTINFO 來完成相同任務.

ERRORS(錯誤)

       ENOBUFS,EPERM對EACCES等.)

       ENOTCONN
              操作只定義於連接的套接字,而該套接字卻沒有連接.

       EINVAL 傳遞無效的參數.  對於發送操作,這可以因發送到一個 blackhole(黑洞) 路由而引發.

       EMSGSIZE
              數據報大於該路徑上的 MTU,並且它不能被分成碎片.

       EACCES 沒有必要權限的使用者試圖執行一項需要某些權限的操作.  這包括: 在沒有 SO_BROADCAST 標
              識設置的情況下發送一個包到廣播地址.    通過一條    禁止的    路由發送包.     在沒有
              CAP_NET_ADMIN         或者有效使用者標識不為0的情況下修改防火牆設置.         在沒有
              CAP_NET_BIND_SERVICE 能力或者有效使用者標識不為零0的情況下綁定一個保留端口.

       EADDRINUSE
              試圖綁定到一個已在使用的地址.

       ENOMEMENOBUFS
              沒有足夠的記憶體可用.

       ENOPROTOOPTEOPNOTSUPP
              傳遞無效的套接字選項.

       EPERM  使用者沒有權限設置高優先級,修改配置或者發送信號到請求的進程或組.

       EADDRNOTAVAIL
              請求一個不存在的接口或者請求的源端地址不是本地的.

       EAGAIN 在一個非阻塞的套接字上進行操作會阻塞.

       ESOCKTNOSUPPORT
              套接字未配置或者請求了一個未知類型的套接字.

       EISCONN
              在一個已經連接的套接字上調用 connect(2).

       EALREADY
              在一個非阻塞的套接字上的連接操作已經在進行中.

       ECONNABORTED
              在一次 accept(2) 執行中連接被關閉.

       EPIPE  連接意外關閉或者被對端關閉.

       ENOENT 在沒有報到達的套接字上調用 SIOCGSTAMP .

       EHOSTUNREACH
              沒有有效路由表記錄匹配目的地址.該錯誤可以被來自遠程路由器的  ICMP消息或者因為本地路
              由表的緣故而引發.

       ENODEV 網路設備不可用或者不適於發送IP.

       ENOPKG 核心子系統沒有配置.

       ENOBUFS, ENOMEM
              沒有足夠的空閒記憶體.  這常常意味著記憶體分配因套接字緩沖區的限制而受限, 而不是因為
              系統記憶體的緣故,但是這也不是100%正確.

       其它錯誤可能由重疊協議族生成;參看 tcp(7), raw(7), udp(7) 和 socket(7).

VERSIONS(版本)

       IP_PKTINFO, IP_MTU, IP_PMTU_DISCOVER, IP_PKTINFO, IP_RECVERRIP_ROUTER_ALERT  是Linux
       2.2中的新選項.

       struct ip_mreqn 也是新出現在Linux 2.2中的.Linux 2.0只支持 ip_mreq.

       sysctl是在Linux 2.2中引入的.

COMPATIBILITY(相容性)

       為了與Linux  2.0相容,仍然支持用過時的  socket(PF_INET,  SOCK_RAW,  protocol)  語法打開一個
       packet(7) 套接字.我們不讚成這麼用,而且應該被 socket(PF_PACKET,  SOCK_RAW,  protocol)  所代
       替.主要的區別就是  新的針對一般鏈接層信息的 sockaddr_ll 地址結構替換了舊的 sockaddr_pkt 地
       址結構.

BUGS

       有許多不連貫的錯誤碼.

       沒有描述用來配置特定IP接口選項和ARP表的ioctl.

AUTHORS(作者)

       該man頁作者是Andi Kleen.

SEE ALSO(另見)

       sendmsg(2), recvmsg(2), socket(7), netlink(7), tcp(7), udp(7), raw(7), ipfw(7).

       RFC791:原始IP規範.
       RFC1122:IPv4主機需求.
       RFC1812:IPv4路由器需求.

[中文版維護人]

       riser <boomer@ccidnet.com>

[中文版最新更新]

       2001/07/19

《中國linux論壇man手冊頁翻譯計劃》:

       http://cmpp.linuxforum.net