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?
Yes.
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
- Run your application which receives packets from
lo
and sends packets toeth1
- 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:
Wireshark
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).
tcpdump
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.
ngrep
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).
libnids
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"
libpcap
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 eitherSOCK_RAW
for raw packets including the link-level header orSOCK_DGRAM
for cooked packets with the link-level header removed. The link-level header information is available in a common format in asockaddr_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. Whenprotocol
is set tohtons(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
Accept Multiple Lines of Input in a Bash Script
"Unknown Symbol in Module" on Module Insertion Despite Export_Symbol
How to Do Simple Arithmetic in Sed Addresses
Calling Windows Subsystem for Linux Apps Through Powershell/Cmd
How to Get Complete Stack Dump from Profiler in Every Sample for Use in Flame Graph
Undocumented Switches for 'Date' Command
Aws Ec2: How to Remount Previous Ebs Volume Using Pivot_Root
Node.Js and Open Files Limit in Linux
How to Use Sed to Replace a String in a File with a Shell Variable
Perl System Calls When Running as Another User Using Sudo
Bash Script to Compile and Run C++ Program
X11 Forwarding Through Google Colab
How to Make 'Docker Run' Inherit Ulimits
How to Get "Instant" Output of "Tail -F" as Input