def _read_routes_post2008(): routes = [] if4_metrics = None # This works only starting from Windows 8/2012 and up. For older Windows another solution is needed # Get-NetRoute -AddressFamily IPV4 | select ifIndex, DestinationPrefix, NextHop, RouteMetric, InterfaceMetric | fl for line in exec_query(['Get-NetRoute', '-AddressFamily IPV4'], ['ifIndex', 'DestinationPrefix', 'NextHop', 'RouteMetric', 'InterfaceMetric']): try: iface = dev_from_index(line[0]) if iface.ip == "0.0.0.0": continue except: continue # try: # intf = pcapdnet.dnet.intf().get_dst(pcapdnet.dnet.addr(type=2, addrtxt=dest)) # except OSError: # log_loading.warning("Building Scapy's routing table: Couldn't get outgoing interface for destination %s", dest) # continue dest, mask = line[1].split('/') ip = "127.0.0.1" if line[0] == "1" else iface.ip # Force loopback on iface 1 if not line[4].strip(): # InterfaceMetric is not available. Load it from netsh if not if4_metrics: if4_metrics = _get_metrics() metric = int(line[3]) + if4_metrics.get(iface.win_index, 0) # RouteMetric + InterfaceMetric else: metric = int(line[3]) + int(line[4]) # RouteMetric + InterfaceMetric routes.append((atol(dest), itom(int(mask)), line[2], iface, ip, metric)) return routes
def make_route(self, host=None, # type: Optional[str] net=None, # type: Optional[str] gw=None, # type: Optional[str] dev=None, # type: Optional[str] metric=1, # type: int ): # type: (...) -> Tuple[int, int, str, str, str, int] from scapy.arch import get_if_addr if host is not None: thenet, msk = host, 32 elif net is not None: thenet, msk_b = net.split("/") msk = int(msk_b) else: raise Scapy_Exception("make_route: Incorrect parameters. You should specify a host or a net") # noqa: E501 if gw is None: gw = "0.0.0.0" if dev is None: if gw: nhop = gw else: nhop = thenet dev, ifaddr, _ = self.route(nhop) else: ifaddr = get_if_addr(dev) return (atol(thenet), itom(msk), gw, dev, ifaddr, metric)
def read_routes(): routes = [] if_index = '(\d+)' dest = '(\d+\.\d+\.\d+\.\d+)/(\d+)' next_hop = '(\d+\.\d+\.\d+\.\d+)' metric_pattern = "(\d+)" delim = "\s+" # The columns are separated by whitespace netstat_line = delim.join([if_index, dest, next_hop, metric_pattern]) pattern = re.compile(netstat_line) ps = sp.Popen(['powershell', 'Get-NetRoute', '-AddressFamily IPV4', '|', 'select ifIndex, DestinationPrefix, NextHop, RouteMetric'], stdout = sp.PIPE, universal_newlines = True) stdout, stdin = ps.communicate(timeout = 10) for l in stdout.split('\n'): match = re.search(pattern,l) if match: try: iface = devname_from_index(int(match.group(1))) addr = ifaces[iface].ip except: continue dest = atol(match.group(2)) mask = itom(int(match.group(3))) gw = match.group(4) # try: # intf = pcapdnet.dnet.intf().get_dst(pcapdnet.dnet.addr(type=2, addrtxt=dest)) # except OSError: # log_loading.warning("Building Scapy's routing table: Couldn't get outgoing interface for destination %s" % dest) # continue routes.append((dest, mask, gw, iface, addr)) return routes
def _read_routes_post2008(): routes = [] if_index = '(\d+)' dest = '(\d+\.\d+\.\d+\.\d+)/(\d+)' next_hop = '(\d+\.\d+\.\d+\.\d+)' metric_pattern = "(\d+)" delim = "\s+" # The columns are separated by whitespace netstat_line = delim.join([if_index, dest, next_hop, metric_pattern]) pattern = re.compile(netstat_line) # This works only starting from Windows 8/2012 and up. For older Windows another solution is needed ps = sp.Popen([ conf.prog.powershell, 'Get-NetRoute', '-AddressFamily IPV4', '|', 'select ifIndex, DestinationPrefix, NextHop, RouteMetric' ], stdout=sp.PIPE, universal_newlines=True) stdout, stdin = ps.communicate() for l in stdout.split('\n'): match = re.search(pattern, l) if match: try: iface = dev_from_index(match.group(1)) if iface.ip == "0.0.0.0": continue except: continue # try: # intf = pcapdnet.dnet.intf().get_dst(pcapdnet.dnet.addr(type=2, addrtxt=dest)) # except OSError: # log_loading.warning("Building Scapy's routing table: Couldn't get outgoing interface for destination %s" % dest) # continue routes.append((atol(match.group(2)), itom(int(match.group(3))), match.group(4), iface, iface.ip)) return routes
def read_routes_post2008(): # XXX TODO: FIX THIS XXX routes = [] if_index = '(\d+)' dest = '(\d+\.\d+\.\d+\.\d+)/(\d+)' next_hop = '(\d+\.\d+\.\d+\.\d+)' metric_pattern = "(\d+)" delim = "\s+" # The columns are separated by whitespace netstat_line = delim.join([if_index, dest, next_hop, metric_pattern]) pattern = re.compile(netstat_line) # This works only starting from Windows 8/2012 and up. For older Windows another solution is needed ps = sp.Popen([conf.prog.powershell, 'Get-NetRoute', '-AddressFamily IPV4', '|', 'select ifIndex, DestinationPrefix, NextHop, RouteMetric'], stdout = sp.PIPE, universal_newlines = True) stdout, stdin = ps.communicate() for l in stdout.split('\n'): match = re.search(pattern,l) if match: try: iface = dev_from_index(match.group(1)) except: continue # try: # intf = pcapdnet.dnet.intf().get_dst(pcapdnet.dnet.addr(type=2, addrtxt=dest)) # except OSError: # log_loading.warning("Building Scapy's routing table: Couldn't get outgoing interface for destination %s" % dest) # continue routes.append((atol(match.group(2)), itom(int(match.group(3))), match.group(4), iface, iface.ip)) return 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 parse_options( self, pool=Net("192.168.1.128/25"), network="192.168.1.0/24", gw="192.168.1.1", # noqa: E501 domain="localnet", renewal_time=60, lease_time=1800): self.domain = domain netw, msk = (network.split("/") + ["32"])[:2] msk = itom(int(msk)) self.netmask = ltoa(msk) self.network = ltoa(atol(netw) & msk) self.broadcast = ltoa(atol(self.network) | (0xffffffff & ~msk)) self.gw = gw if isinstance(pool, six.string_types): pool = Net(pool) if isinstance(pool, Iterable): pool = [ k for k in pool if k not in [gw, self.network, self.broadcast] ] # noqa: E501 pool.reverse() if len(pool) == 1: pool, = pool self.pool = pool self.lease_time = lease_time self.renewal_time = renewal_time self.leases = {}
def ifadd(self, iff, addr): # type: (str, str) -> None self.invalidate_cache() the_addr, the_msk_b = (addr.split("/") + ["32"])[:2] the_msk = itom(int(the_msk_b)) 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, 1))
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, route in enumerate(self.routes): net, msk, gw, iface, addr = route 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 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 _read_routes_c(ipv6=False): """Retrieve Windows routes through a GetIpForwardTable2 call. This is not available on Windows XP !""" af = socket.AF_INET6 if ipv6 else socket.AF_INET sock_addr_name = 'Ipv6' if ipv6 else 'Ipv4' sin_addr_name = 'sin6_addr' if ipv6 else 'sin_addr' metric_name = 'ipv6_metric' if ipv6 else 'ipv4_metric' ip_len = 16 if ipv6 else 4 if ipv6: lifaddr = in6_getifaddr() routes = [] def _extract_ip_netmask(obj): ip = obj[sock_addr_name][sin_addr_name] ip = bytes(bytearray(ip['byte'])) # Extract netmask netmask = (ip_len - (len(ip) - len(ip.rstrip(b"\x00")))) * 8 # Build IP ip = inet_ntop(af, ip) return ip, netmask for route in GetIpForwardTable2(af): # Extract data ifIndex = route['InterfaceIndex'] _dest = route['DestinationPrefix'] dest, netmask = _extract_ip_netmask(_dest['Prefix']) nexthop, _ = _extract_ip_netmask(route['NextHop']) metric = route['Metric'] # Build route try: iface = dev_from_index(ifIndex) if iface.ip == "0.0.0.0": continue except ValueError: continue ip = iface.ip # RouteMetric + InterfaceMetric metric = metric + getattr(iface, metric_name) if ipv6: _append_route6(routes, dest, netmask, nexthop, iface, lifaddr, metric) else: routes.append( (atol(dest), itom(int(netmask)), nexthop, iface, ip, metric)) return routes
def ifchange(self, iff, addr): # type: (str, str) -> None self.invalidate_cache() the_addr, the_msk_b = (addr.split("/") + ["32"])[:2] the_msk = itom(int(the_msk_b)) the_rawaddr = atol(the_addr) the_net = the_rawaddr & the_msk for i, route in enumerate(self.routes): net, msk, gw, iface, addr, metric = route if iff != iface: continue if gw == '0.0.0.0': self.routes[i] = (the_net, the_msk, gw, iface, the_addr, metric) # noqa: E501 else: self.routes[i] = (net, msk, gw, iface, the_addr, metric) conf.netcache.flush()
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 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, route in enumerate(self.routes): net, msk, gw, iface, addr, metric = route if scapy.consts.WINDOWS: if iff.guid != iface.guid: continue elif iff != iface: continue if gw == '0.0.0.0': self.routes[i] = (the_net, the_msk, gw, iface, the_addr, metric) # noqa: E501 else: self.routes[i] = (net, msk, gw, iface, the_addr, metric) conf.netcache.flush()
def parse_options(self, pool=Net("192.168.1.128/25"), network="192.168.1.0/24", gw="192.168.1.1", # noqa: E501 domain="localnet", renewal_time=60, lease_time=1800): self.domain = domain netw, msk = (network.split("/") + ["32"])[:2] msk = itom(int(msk)) self.netmask = ltoa(msk) self.network = ltoa(atol(netw) & msk) self.broadcast = ltoa(atol(self.network) | (0xffffffff & ~msk)) self.gw = gw if isinstance(pool, six.string_types): pool = Net(pool) if isinstance(pool, Iterable): pool = [k for k in pool if k not in [gw, self.network, self.broadcast]] # noqa: E501 pool.reverse() if len(pool) == 1: pool, = pool self.pool = pool self.lease_time = lease_time self.renewal_time = renewal_time self.leases = {}
def read_routes(): routes = [] if_index = '(\d+)' dest = '(\d+\.\d+\.\d+\.\d+)' mask = '(\d+\.\d+\.\d+\.\d+)' next_hop = '(\d+\.\d+\.\d+\.\d+)' metric_pattern = "(\d+)" delim = "\s+" # The columns are separated by whitespace netstat_line = delim.join([if_index, dest, mask, next_hop, metric_pattern]) pattern = re.compile(netstat_line) # This way works on Windows 7+ (probably as well on older Windows systems). Note the | ft in the end to keep table # format, as powershell will change from table to line based format when it has to print more than 4 columns ps = sp.Popen([ 'powershell', 'Get-WMIObject', 'Win32_IP4RouteTable', '|', 'select InterfaceIndex, Destination, Mask, NextHop, Metric1', '|', 'ft' ], stdout=sp.PIPE, universal_newlines=True) stdout, stdin = ps.communicate(timeout=10) for l in stdout.split('\n'): match = re.search(pattern, l) if match: try: iface = devname_from_index(int(match.group(1))) addr = ifaces[iface].ip except: continue dest = atol(match.group(2)) mask = itom( sum([ len(bin(int(a)).replace("0", "")) - 1 for a in match.group(3).split(".") ])) gw = match.group(4) # try: # intf = pcapdnet.dnet.intf().get_dst(pcapdnet.dnet.addr(type=2, addrtxt=dest)) # except OSError: # log_loading.warning("Building Scapy's routing table: Couldn't get outgoing interface for destination %s" % dest) # continue routes.append((dest, mask, gw, iface, addr)) return routes
def _read_routes_post2008(): routes = [] # This works only starting from Windows 8/2012 and up. For older Windows another solution is needed # Get-NetRoute -AddressFamily IPV4 | select ifIndex, DestinationPrefix, NextHop, RouteMetric, InterfaceMetric | fl for line in exec_query(['Get-NetRoute', '-AddressFamily IPV4'], [ 'ifIndex', 'DestinationPrefix', 'NextHop', 'RouteMetric', 'InterfaceMetric' ]): try: iface = dev_from_index(line[0]) if iface.ip == "0.0.0.0": continue except: continue # try: # intf = pcapdnet.dnet.intf().get_dst(pcapdnet.dnet.addr(type=2, addrtxt=dest)) # except OSError: # log_loading.warning("Building Scapy's routing table: Couldn't get outgoing interface for destination %s", dest) # continue dest, mask = line[1].split('/') routes.append((atol(dest), itom(int(mask)), line[2], iface, iface.ip, int(line[3]) + int(line[4]))) return routes