/usr/lib/python3/dist-packages/scapy/route.py is in python3-scapy 0.23-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | ## This file is part of Scapy
## See http://www.secdev.org/projects/scapy for more informations
## Copyright (C) Philippe Biondi <phil@secdev.org>
## This program is published under a GPLv2 license
"""
Routing and handling of network interfaces.
"""
import socket
from scapy.arch import read_routes,get_if_addr,LOOPBACK_NAME
from scapy.utils import atol,ltoa,itom
from scapy.config import conf
from scapy.error import Scapy_Exception,warning
##############################
## Routing/Interfaces stuff ##
##############################
class Route:
def __init__(self):
self.resync()
self.s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.cache = {}
def invalidate_cache(self):
self.cache = {}
def resync(self):
self.invalidate_cache()
self.routes = read_routes()
def __repr__(self):
rt = "Network Netmask Gateway Iface Output IP\n"
for net,msk,gw,iface,addr in self.routes:
rt += "%-15s %-15s %-15s %-15s %-15s\n" % (ltoa(net),
ltoa(msk),
gw,
iface,
addr)
return rt
def make_route(self, host=None, net=None, gw=None, dev=None):
if host is not None:
thenet,msk = host,32
elif net is not None:
thenet,msk = net.split("/")
msk = int(msk)
else:
raise Scapy_Exception("make_route: Incorrect parameters. You should specify a host or a net")
if gw is None:
gw="0.0.0.0"
if dev is None:
if gw:
nhop = gw
else:
nhop = thenet
dev,ifaddr,x = self.route(nhop)
else:
ifaddr = get_if_addr(dev)
return (atol(thenet), itom(msk), gw, dev, ifaddr)
def add(self, *args, **kargs):
"""Ex:
add(net="192.168.1.0/24",gw="1.2.3.4")
"""
self.invalidate_cache()
self.routes.append(self.make_route(*args,**kargs))
def delt(self, *args, **kargs):
"""delt(host|net, gw|dev)"""
self.invalidate_cache()
route = self.make_route(*args,**kargs)
try:
i=self.routes.index(route)
del(self.routes[i])
except ValueError:
warning("no matching route found")
def ifchange(self, iff, addr):
self.invalidate_cache()
the_addr,the_msk = (addr.split("/")+["32"])[:2]
the_msk = itom(int(the_msk))
the_rawaddr = atol(the_addr)
the_net = the_rawaddr & the_msk
for i in range(len(self.routes)):
net,msk,gw,iface,addr = self.routes[i]
if iface != iff:
continue
if gw == '0.0.0.0':
self.routes[i] = (the_net,the_msk,gw,iface,the_addr)
else:
self.routes[i] = (net,msk,gw,iface,the_addr)
conf.netcache.flush()
def ifdel(self, iff):
self.invalidate_cache()
new_routes=[]
for rt in self.routes:
if rt[3] != iff:
new_routes.append(rt)
self.routes=new_routes
def ifadd(self, iff, addr):
self.invalidate_cache()
the_addr,the_msk = (addr.split("/")+["32"])[:2]
the_msk = itom(int(the_msk))
the_rawaddr = atol(the_addr)
the_net = the_rawaddr & the_msk
self.routes.append((the_net,the_msk,'0.0.0.0',iff,the_addr))
def route(self,dest,verbose=None):
if type(dest) is list and dest:
dest = dest[0]
if dest in self.cache:
return self.cache[dest]
if verbose is None:
verbose=conf.verb
# Transform "192.168.*.1-5" to one IP of the set
dst = dest.split("/")[0]
dst = dst.replace("*","0")
while True:
l = dst.find("-")
if l < 0:
break
m = (dst[l:]+".").find(".")
dst = dst[:l]+dst[l+m:]
dst = atol(dst)
pathes=[]
for d,m,gw,i,a in self.routes:
aa = atol(a)
#Commented out after issue with virtual network with local address 0.0.0.0
#if aa == dst:
# pathes.append((0xffffffff,(LOOPBACK_NAME,a,"0.0.0.0")))
if (dst & m) == (d & m):
pathes.append((m,(i,a,gw)))
if not pathes:
if verbose:
warning("No route found (no default route?)")
return LOOPBACK_NAME,"0.0.0.0","0.0.0.0" #XXX linux specific!
# Choose the more specific route (greatest netmask).
# XXX: we don't care about metrics
pathes.sort()
ret = pathes[-1][1]
self.cache[dest] = ret
return ret
def get_if_bcast(self, iff):
for net, msk, gw, iface, addr in self.routes:
if (iff == iface and net != 0):
bcast = atol(addr)|(~msk&0xffffffff); # FIXME: check error in atol()
return ltoa(bcast);
warning("No broadcast address found for iface %s\n" % iff);
conf.route=Route()
#XXX use "with"
_betteriface = conf.route.route("0.0.0.0", verbose=0)[0]
if _betteriface != LOOPBACK_NAME:
conf.iface = _betteriface
del(_betteriface)
|