1、原始套接字的协议是否可以设置为IPPRORO_TCP?UDP和TCP分组没有对应的套接字,此时会不会将其传递到原始套接口?
答:
(1) 可以。对于socket()函数,在流式套接字编程中第二个参数是SOCK_STREAM,而对于数据报套接字编程,第二个参数是SOCK_DGRAM,在这两种情况下,第三个参数可以填0,这样系统会自动匹配相应的协议。
而原始套接字编程中,第二个参数是SOCK_RAW,在这种情况下,第三个参数必须指明相应的协议,协议类型的常用取值有 IPPROTO_IP、IPPROTO_ICMP、IPPROTO_TCP、IPPROTO和IPPROTO_RAW。
(2) 不会。接收到的UDP或者TCP分组绝不传递到任何原始套接字,如果一个进程想要读取含有UDP分组或TCP分组的IP数据报,它就必须在数据链路层读取这些分组(即使用IPPROTO_IP选项读取整个IP包)。
使用 IPPROTO_TCP 和 IPPROTO_UDP选项的原始套接字时,只能发TCP或者UDP数据包(是否需要对IP头部的操作由 IP_HDRINCL 决定),而不能接收TCP或者UDP协议的数据包,因为TCP和UDP数据包由内核进行协议的判断,并查找IP地址和端口号相匹配的socket连接来递交数据包,而原始套接字没有端口的概念,因此不能接收TCP或者UDP的数据包。原始套接字只能通过IPPROTO_IP来获得整个IP数据包,然后从中提取TCP和UDP的数据。
2、原始套接字构造IP头的情况下,用send,还是sendto?如果是sendto的话,参数to和构造的首部中的IP地址不一致,或者connect、bind的IP地址与构造的首部中的IP不一致,如何处理?
答:
(1) 原始套接口发送数据通常用sendto,在第五个参数to中指定要发送的目的地址。如果调用过connect,目的地址已经设定,发送数据时,可以直接调用send,当然也可以用sendto,并且第五个参数to设置为NULL。当to不为NULL时,系统会把数据发送到to所指定的目的地址
(2) 会失败,错误码为WSAEINTR。目的是限制恶意的代码去做拒绝服务攻击或者不允许发送带有假IP地址的欺骗数据报。
原文地址:https://www.cnblogs.com/cyx-b/p/12638191.html