gpt4 book ai didi

sockets - IPPROTO_IP 和 IPPROTO_RAW 有什么区别?

转载 作者:行者123 更新时间:2023-12-03 18:38:55 39 4
gpt4 key购买 nike

谁能解释或给我一个 IPPROTO_IP 的定义?并帮助我了解 IPPROTO_IP 之间的区别和 IPPROTO_RAW ?

最佳答案

这是我的 /usr/include/netinet.in.h 的摘录Linux 上的文件。

/* Standard well-defined IP protocols.  */
enum
{
IPPROTO_IP = 0, /* Dummy protocol for TCP. */
#define IPPROTO_IP IPPROTO_IP
IPPROTO_ICMP = 1, /* Internet Control Message Protocol. */
#define IPPROTO_ICMP IPPROTO_ICMP
[.......]
IPPROTO_TCP = 6, /* Transmission Control Protocol. */
#define IPPROTO_TCP IPPROTO_TCP
IPPROTO_UDP = 17, /* User Datagram Protocol. */
#define IPPROTO_UDP IPPROTO_UDP
[.......]
IPPROTO_RAW = 255, /* Raw IP packets. */
#define IPPROTO_RAW IPPROTO_RAW
IPPROTO_MAX
};

这是 man socket 的摘录:

The protocol specifies a particular protocol to be used with the socket. Normally only a single protocol exists to support a particular socket type within a given protocol family, in which case protocol can be specified as 0. However, it is possible that many protocols may exist, in which case a particular protocol must be specified in this manner. The protocol number to use is specific to the “communication domain” in which communication is to take place; see protocols(5). See getprotoent(3) on how to map protocol name strings to protocol numbers.



IPPROTO_IP

in.h文件,评论说: Dummy protocol for TCP.这个常量的值为 0。它实际上是一个 根据 socket 类型和系列自动选择 .
如果你使用它,并且套接字类型是 SOCK_STREAM 家庭是 AF_INET ,则协议(protocol)将自动为 TCP(与您使用 IPPROTO_TCP 完全相同)。
如果你使用 IPPROTO_IP 连同 AF_INET SOCK_RAW ,你会有一个错误,因为在这种情况下内核不能自动选择协议(protocol)。

IPPROTO_RAW

通常,您与 OSI 模型的第 4 层(TCP 或 UDP)进行交互。如果您使用 IPPROTO_RAW ,您将能够直接与第 3 层 (IP) 交互。这意味着你的水平更低。例如, 您可以编辑 IP 数据包的 header 和有效负载 (通常,内核将在其他模式下处理 header )。编辑有效负载意味着您​​可以自由地将您想要的内容直接放入 IP 有效负载中。内部不会有任何 TCP 段或其他任何东西。你可以在里面做你想做的事!

这显示了 IP 数据包的内存布局:
 0                   1                   2                   3   
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

考虑阅读 man 7 raw其中包含大量有关使用 RAW 套接字的信息。
   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 capa‐
bility 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 proto‐
cols see RFC 1700 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. │
└──────────────────────┴────────────────────────────┘

因此,为简单起见,您可以手动编辑 IP header 的所有字段,除了以下将始终由内核填充的字段:
  • 校验和;
  • 总长度。

  • 您可以使用 struct ip 编辑这些字段。

    摘自 /usr/include/netinet.ip.h
    /*
    * Structure of an internet header, naked of options.
    */
    struct ip
    {
    #if __BYTE_ORDER == __LITTLE_ENDIAN
    unsigned int ip_hl:4; /* header length */
    unsigned int ip_v:4; /* version */
    #endif
    #if __BYTE_ORDER == __BIG_ENDIAN
    unsigned int ip_v:4; /* version */
    unsigned int ip_hl:4; /* header length */
    #endif
    u_int8_t ip_tos; /* type of service */
    u_short ip_len; /* total length */
    u_short ip_id; /* identification */
    u_short ip_off; /* fragment offset field */
    #define IP_RF 0x8000 /* reserved fragment flag */
    #define IP_DF 0x4000 /* dont fragment flag */
    #define IP_MF 0x2000 /* more fragments flag */
    #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
    u_int8_t ip_ttl; /* time to live */
    u_int8_t ip_p; /* protocol */
    u_short ip_sum; /* checksum */
    struct in_addr ip_src, ip_dst; /* source and dest address */
    };

    为什么以及何时使用 IPPROTO_RAW?

    好吧,这取决于您要制作的应用程序。有些应用程序有非常具体的需求,只需要有很大的灵 active 。
    例如,如果你想实现 traceroute ,您将希望每次都增加 TTL。

    您可以使用 setsockopt 更改 TTL ,但是如果你有很多头字段要手动更改,最好接管IP头的完全控制!

    另一个用途是如果您想在 IP 之上实现自己的协议(protocol)。

    关于sockets - IPPROTO_IP 和 IPPROTO_RAW 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24590818/

    39 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com