如何初始化用于VLAN嗅探的原始套接字 [英] How to initialize raw socket for VLAN sniffing

查看:73
本文介绍了如何初始化用于VLAN嗅探的原始套接字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建可从不同VLAN嗅探DHCP报价的软件,而我的问题是我接收到的数据包不包含VLAN标记.我正在使用原始套接字,并且尝试启用混杂模式,但无济于事.

I'm trying to create software that sniffes DHCP-offers from diffrent VLAN's and my problem is that the packets recv'ed by me contains no VLAN-tags. I'm using raw sockets, and i've tried to enable promiscuous mode, but no avail.

问题是如何指示内核将数据包中的所有数据保持完整?

Question is that how to instruct kernel to keep all of the data in the packet intact?

使用wireshark时,我可以看到VLAN报头设置为ok的回复数据包,但是我收到的数据已删除了所有VLAN信息.

When using wireshark i can see the reply packet with the VLAN header set ok, but my recv'ed data has all the VLAN information removed.

提前谢谢!

-劳里(Lauri)

推荐答案

这很旧,但是仍然没有解决:

This is old, but this still hasn't been solved:

在NIC上启用VLAN卸载后,Linux将不会在recv返回的数据中传递VLAN标记.而是在控制消息中传递VLAN TCI.

When VLAN offload is enabled on the NIC Linux will not deliver the VLAN tag in the data returned by recv. Instead, it delivers the VLAN TCI in a control message.

要获取控制字段,您需要使用 PACKET_AUXDATA ,这会将以下内容添加到辅助数据中:

To get the control fields, you need to use PACKET_AUXDATA, which will add the following to ancillary data:

 struct tpacket_auxdata {
      __u32 tp_status;
      __u32 tp_len;      /* packet length */
      __u32 tp_snaplen;  /* captured length */
      __u16 tp_mac;
      __u16 tp_net;
      __u16 tp_vlan_tci;
      __u16 tp_padding;
  };

例如

sock.setsockopt(SOL_PACKET, PACKET_AUXDATA, 1)

完成后,使用 recvmsg()并遍历辅助数据以查找 PACKET_AUXDATA .从中取出tp_vlan_tci,然后将其重新注入数据包数据中.

Once that is done, use recvmsg() and iterate through the ancillary data looking for PACKET_AUXDATA. Get tp_vlan_tci out of it, and inject this back into the packet data.

代码示例

  • C:libpcap

https://github.com/the-tcpdump-group/libpcap/blob/3a7962215f4f3b13ac792ad0e0487a53c0f1178e/pcap-linux.c#L1756

  • Python
import ctypes, socket

# From bits/socket.h
SOL_PACKET = 263
# From asm/socket.h
SO_ATTACH_FILTER = 26
ETH_P_8021Q = 0x8100
TP_STATUS_VLAN_VALID = 1 << 4

class tpacket_auxdata(ctypes.Structure):
    _fields_ = [
        ("tp_status", ctypes.c_uint),
        ("tp_len", ctypes.c_uint),
        ("tp_snaplen", ctypes.c_uint),
        ("tp_mac", ctypes.c_ushort),
        ("tp_net", ctypes.c_ushort),
        ("tp_vlan_tci", ctypes.c_ushort),
        ("tp_padding", ctypes.c_ushort),
    ]

def _recv_raw(sock, x=65535):
    """Internal function to receive a Packet,
    and process ancillary data.
    """
    flags_len = socket.CMSG_LEN(4096)
    pkt, ancdata, flags, sa_ll = sock.recvmsg(x, flags_len)
    if not pkt:
        return pkt, sa_ll
    for cmsg_lvl, cmsg_type, cmsg_data in ancdata:
        # Check available ancillary data
        if (cmsg_lvl == SOL_PACKET and cmsg_type == PACKET_AUXDATA):
            # Parse AUXDATA
            auxdata = tpacket_auxdata.from_buffer_copy(cmsg_data)
            if auxdata.tp_vlan_tci != 0 or \
                    auxdata.tp_status & TP_STATUS_VLAN_VALID:
                # Insert VLAN tag
                tag = struct.pack(
                    "!HH",
                    ETH_P_8021Q,
                    auxdata.tp_vlan_tci
                )
                    pkt = pkt[:12] + tag + pkt[12:]
        return pkt

(来自 https://github.com/secdev/scapy )

这篇关于如何初始化用于VLAN嗅探的原始套接字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆