I'd like to make something like this:
10.1.1.0/24 10.1.2.0/24
+------------+ +------------+ +------------+
| | | | | |
| | | | | |
| A d +-------+ e B f +-------+ g C |
| | | | | |
| | | | | |
+------------+ +------------+ +------------+
d e f g
10.1.1.1 10.1.1.2 10.1.2.1 10.1.2.2
So that A
can send packets to C
through B
.
I attempted to build this thing by running a scapy program on B
that would sniff ports e
and f
, and in each case modify the destination IP and MAC address in the packet and then send it along through the other interface. Something like:
my_macs = [get_if_hwaddr(i) for i in get_if_list()]
pktcnt = 0
dest_mac_address = discover_mac_for_ip(dest_ip) #
output_mac = get_if_hwaddr(output_interface)
def process_packet(pkt):
# ignore packets that were sent from one of our own interfaces
if pkt[Ether].src in my_macs:
return
pktcnt += 1
p = pkt.copy()
# if this packet has an IP layer, change the dst field
# to our final destination
if IP in p:
p[IP].dst = dest_ip
# if this packet has an ethernet layer, change the dst field
# to our final destination. We have to worry about this since
# we're using sendp (rather than send) to send the packet. We
# also don't fiddle with it if it's a broadcast address.
if Ether in p \
and p[Ether].dst != 'ff:ff:ff:ff:ff:ff':
p[Ether].dst = dest_mac_address
p[Ether].src = output_mac
# use sendp to avoid ARP'ing and stuff
sendp(p, iface=output_interface)
sniff(iface=input_interface, prn=process_packet)
However, when I run this thing (full source here) all sorts of crazy things start to happen... Some of the packets get through, and I even get some responses (testing with ping
) but there's some type of feedback loop that's causing a bunch of duplicate packets to get sent...
Any ideas what's going on here? Is it crazy to try to do this?
I'm kind of suspicious that the feedback loops are being caused by the fact that B
is doing some processing of its own on the packets... Is there any way to prevent the OS from processing a packet after I've sniffed it?