原始套接字提供普通的TCP和UDP所不提供的能力
- 可以读写ICMPv4,IGMPv4和ICMPv6等分组。这个能力使得使用ICMP和IGMP构筑的应用程序能够完全作为用户进程处理。
- 可以读写内核不处理其协议字段的IPv4数据报。大多数内核仅仅处理IP协议字段为1(ICMP),2(IGMP),6(TCP),和17(UDP)的数据报。
- 有了原始套接字,进程还可以使用IP_HDRINCL套接字选项自行构造IPv4首部。
1. 原始套接字创建
- 只有超级用户才能创建原始套接字。
- 可以在原始套接字上调用bind函数。bind仅仅设置本地地址(从这个原始套接字发送的所有数据报的源IP地址)
- 可以在原始套接字上调用connect函数。其设置外地地址,调用connect之后可以把sendto调用改为write和send调用。
2.原始套接字的输出
- 普通输出通过调用sendto或sendmsg并指定目的IP地址完成。若套接字已连接,也可以使用write,writev,send。
- 如果未开启IP_HDRINCL选项,那么进程让内核发送的数据的起始地址指的是IP首部之后的第一个字节。
- 如果开启IP_HDRINCL选项,则起始地址指的是IP首部的第一个字节。
3.原始套接字的输入
- 接收到的UDP分组和TCP分组绝不传递到任何原始套接字。若一个进程想要读取含有UDP分组或TCP分组的IP数据报,就必须使用数据链路层。
- BSD系统把不是回射请求,时间戳请求,或地址掩码请求(这三类消息完全由内核处理)的所有接受到的ICMP分组传递给原始套接字。
- 无论何时往一个原始IPv4套接字递送一个接受到的数据报,传递给该套接字所在进程的都是包括IP首部在内的完整数据报。IPv6只传递净荷。