我开始编写数据包嗅探器,并且我搜索了传递给socket()
函数的正确参数,以便使用以太网头捕获数据包。
我注意到在这个tutorial中,为了接收以太网报头,他们改变了这一行:
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
到这一行:
s = socket.socket( socket.AF_PACKET , socket.SOCK_RAW , socket.ntohs(0x0003))
我的问题是:
我从link了解到AF_INET
带有原始套接字不会给我以太网头。我的问题是为什么?
为什么他也从IPPROTO_TCP
更改为ntohs(0x0003)
我知道这是GGP协议。据我所知,第三个参数表示套接字将接收的协议。如果协议参数是GGP,那么套接字将查找具有GGP作为其互联网层协议的数据包,不是吗?那为什么他们通过GGP而不是TCP或IP?毕竟,几乎每个PDU都有IP和\或TCP \ UDP作为其数据协议。我的数据包嗅探器的第三个参数是什么?
除了第二个问题,我认为我没有得到第三个参数的目标。如果这是IPPROTO_TCP,套接字将捕获网络层中具有TCP的数据包(例如,不是UDP)?如果我将通过IPPROTO_IP,套接字将捕获具有IP作为其互联网层协议的数据包,而无需检查其他层的协议(套接字对于网络层使用什么协议无关紧要?它只关心IP是否存在为互联网层协议)?
感谢并抱歉语法错误(英语不是我的第一语言)。
答案 0 :(得分:1)
如果您选中linux/if_ether.h,则会看到
#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */
所以ETH_P_ALL的值是0x0003。本教程的作者使用0x0003而不是ETH_P_ALL,因为在python中使用某些系统时会发生“未定义”错误。
答案 1 :(得分:0)
可以在网络堆栈的不同层设置原始套接字功能,以便内核能够在较低级别为您执行某些工作(例如:以太网制作)。
在您找到示例的网站上对GGP协议的更改可能有意义,但这样做很难看,应该使用getprotoent()
而不是使用幻数。
是的,您可以调整(过滤)数据包捕获的发生方式。如果要捕获所有数据包,请使用ETH_P_ALL:
当协议设置为htons(ETH_P_ALL)时,所有协议都是 接收。