![通过 gretap 使用原始套接字发送数据](https://linux22.com/image/218207/%E9%80%9A%E8%BF%87%20gretap%20%E4%BD%BF%E7%94%A8%E5%8E%9F%E5%A7%8B%E5%A5%97%E6%8E%A5%E5%AD%97%E5%8F%91%E9%80%81%E6%95%B0%E6%8D%AE.png)
我正在尝试将 IS-IS 数据包写入具有 ISO (0x00fe) 协议类型的 gretap 接口。在这种情况下,没有以太网标头,因此我使用原始套接字。 gretap 总是将 0x6558 作为 GRE 标头中的协议类型,有没有办法让 gretap 使用不同的协议类型(即 0x00fe),以便接收方期望在 GRE 标头之后立即看到 IS-IS 数据包(即没有首先是以太网头)?
跟进:
我认为协议类型是硬编码的,即(来自内核中的 ip_gre.c):
761 static netdev_tx_t gre_tap_xmit(struct sk_buff *skb,
762 struct net_device *dev)
763 {
...
776
777 __gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_TEB));
778 return NETDEV_TX_OK;
符号 ETH_P_TEB 是透明以太网桥类型 (0x6558),因此没有选项可以设置该值。这是不幸的,因为如果使用原始套接字,我们可能希望在 GRE 上生成不同的封装。我将尝试修改内核模块。
答案1
看起来我可以使用 IP gre 接口和原始套接字而不是 gretap 来完成我想要的事情。在这种情况下,可以使用 sendto() 调用中传递的 struct sockaddr_ll 的 sll_protocol 字段来设置协议类型,并且使用原始套接字可以控制封装。