How to Inject a Raw L2 Packet as an Incoming Packet to an Interface on Linux

How to inject a raw L2 packet as an incoming packet to an interface on Linux?

If you have the native linux bridge module available then you can use it in this way. Create a bridge

brctl addbr <brname>

Now create a virtual eth pair (default names veth0, veth1). veths are connected L2 devices

ip link add type veth
ifconfig veth0 up
ifconfig veth1 <some_ip> up

Now add your specific interface, lets say eth0, and one side of the veth pair to this bridge.

brctl addif <brname> eth0
brctl addif <brname> veth0

This adds both these interfaces to the bridge. Now when you send traffic on veth0, you should be able to get it on eth0 also(based on normal L2 switch functionality). To send traffic on veth0 you simply need to pump traffic into veth1 since both of them are connected internally. So lets say you want to use tcpreplay, just do

tcpreply -i veth1 yourpcap.pcap

Let us know how it goes

pcap_inject on a disconnected interface

Now the NIC doesn't have an ethernet cable connected to it.

Then what useful result do you expect to get by sending packets on that NIC?

I know that pcap_open_live won't tell whether the device opened supports sending

Whether the device is up or not can change over time, so any answer you get from pcap_open_live() could be incorrect by the time you actually try to send the packet.

so I get errors from pcap_inject (errno 100)

Searching for 100 in Linux errno.h reveals:

#define ENETDOWN    100 /* Network is down */

I guess the Linux networking doesn't like it when people try to send packets on an interface that's down with a send() system call, which is what libpcap does.

Is this to be expected?


If I simply use tcpreplay from the cmd line, it finishes and presents no error

tcpreplay has a whole bunch of different mechanisms it uses to send packets. See sendpacket() in the sendpacket.c source file in the tcpreplay source. Some of them might, for example, silently drop packets being sent on a dead interface, rather than reporting an error, and it might be using one of those mechanisms.

simulate incoming packets on a network interface in linux

Replace eth0 with lo

  1. Run your application which receives packets from lo and sends packets to eth1
  2. Run another program (packet generator) which send packets to lo

every packet send to lo will be received by lo again, so your application will receive packets from your packet generator.

if your lo is busy with other packets, you can add more loopback device by kernel argument max_loop=x

View - but not intercept - all IPv4 traffic to Linux computer

Yes, you can see all the packets that arrive at your network interface. There are several options to access or view them. Here a small list of possible solutions, where the first one is the easiest and the last one the hardest to utilize:


I'd say this is pretty much the standard when it comes to protocol analyzers with a GUI (uses libpcap). It has tons of options, a nice GUI, great filtering capabilities and reassembles IP datagrams. It uses libpcap and can also show the raw ethernet frame data. For example it allows you to see layer 2 packets like ARP. Furthermore you can capture the complete data arriving at your network interface in a file that can later be analyzed (also in Wireshark).


Very powerful, similar features like Wireshark but a command line utility, which also uses libpcap. Can also capture/dump the complete interface traffic to a file. You can view the dumped data in Wireshark since the format is compatible.


This is known as the "network grep" and is similar to tcpdump but supports regular expressions (regex) to filter the payload data. It allows to save captured data in the file format supported by Wireshark and tcpdump (also uses libpcap).


Quotation from the official git repository:

"Libnids is a library that provides a functionality of one of NIDS
(Network Intrusion Detection System) components, namely E-component. It means
that libnids code watches all local network traffic [...] and provides convenient information on them to
analyzing modules of NIDS. Libnids performs:

  • assembly of TCP segments into TCP streams
  • IP defragmentation
  • TCP port scan detection"


Of course you can also write your own programs by using the library directly. Needless to say, this requires more efforts.

Raw or Packet Sockets

In case you want to do all the dirty work yourself, this is the low level option, which of course also allows you to do everything you want. The tools listed above use them as a common basis. Raw sockets operate on OSI layer 3 and packet sockets on layer 2.

Note: This is not meant to be a complete list of available tools or options. I'm sure there are much more but these are the most common ones I can think of.

How does the AF_PACKET socket work in Linux?

What happens in the kernel?

The kernel simply duplicates the packets as soon as it receives them from the physical layer (for incoming packets) or just before sending them out to the physical layer (for outgoing packets). One copy of each packet is sent to your socket (if you use ETH_PH_ALL then you are listening on all interfaces, but you could also bind(2) to a particular one). After a copy is sent to your socket, the other copy then continues being processed like it normally would (e.g. identifying and decoding the protocol, checking firewall rules, etc).

How am I seeing all the incoming and outgoing packets, but not "hijacking" them?

In order for hijacking to happen, you would need to write data to the socket injecting new packets (accurately crafted depending on the protocol you want to hijack). If you only read incoming packets, you are merely sniffing, without hijacking anything.

does the kernel clone the packet and sends it in addition to the socket I opened?

Yes, that's basically what happens. This image could help you visualize it.

man 7 packet also describes this:

Packet sockets are used to receive or send raw packets at the device driver (OSI Layer 2) level. They allow the user to implement protocol modules in user space on top of the physical layer.

The socket_type is either SOCK_RAW for raw packets including the link-level header or SOCK_DGRAM for cooked packets with the link-level header removed. The link-level header information is available in a common format in a sockaddr_ll structure. protocol is the IEEE 802.3 protocol number in network byte order. See the <linux/if_ether.h> include file for a list of allowed protocols. When protocol is set to htons(ETH_P_ALL), then all protocols are received. All incoming packets of that protocol type will be passed to the packet socket before they are passed to the protocols implemented in the kernel.

Related Topics

Leave a reply