How to Initialize Raw Socket for Vlan Sniffing

Reading VLAN field of a raw ethernet packet in Python

Late to the party, see https://stackoverflow.com/a/59760058/5459467 for full details.

I advise to use scapy's sockets (conf.L2socket or sniff) that have this code implemented. Otherwise use the snippet below:

import ctypes, socket

# From bits/socket.h
SOL_PACKET = 263
# From asm/socket.h
SO_ATTACH_FILTER = 26
ETH_P_8021Q = 0x8100
PACKET_AUXDATA = 8
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

(From https://github.com/secdev/scapy/pull/2091)

But first, while starting your socket, use

sock.setsockopt(SOL_PACKET, PACKET_AUXDATA, 1)

Linux user space L2 control protocols

I think the best way to implement this would be to add a field in sk_buff to store your special L2 header. If I understand correctly, headers should be preserved when passing sk_buffs from one layer to another, albeit, you might need to add some code to skb_clone.

If you reach this point, sending this value to user-space is only limited by your imagination. For example, you could

  1. store the value in the socket structure sock and return it later using an ioctl;
  2. return the value in recvfrom's src_addr directly

Hope this help.

How can I make my JUnit tests run in random order?

You do have a Sortable but I can't see how you would use it.

You could extend BlockJUnit4ClassRunner and have computeTestMethods() return a randomized copy of super.computeTestMethods(). Then use the @RunWith to set that as the runner to use.

e.g.

package com.stackoverflow.mlk;

import java.util.Collections;

import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;

public class RandomBlockJUnit4ClassRunner extends BlockJUnit4ClassRunner {

public RandomBlockJUnit4ClassRunner(Class<?> klass)
throws InitializationError {
super(klass);
}

protected java.util.List<org.junit.runners.model.FrameworkMethod> computeTestMethods() {
java.util.List<org.junit.runners.model.FrameworkMethod> methods = super.computeTestMethods();
Collections.shuffle(methods);
return methods;
}

}

Then

@RunWith(com.stackoverflow.mlk.RandomBlockJUnit4ClassRunner.class)
public class RandomOrder {
@Test
public void one() {
}

@Test
public void two() {
}

@Test
public void three() {
}
}


Related Topics



Leave a reply



Submit