Provide best route to IPv6 destination address, based on Scapy internal routing table content. When a set of address is passed (e.g. ``2001:db8:cafe:*::1-5``) an address of the set is used. Be aware of that behavior when using wildcards in upper parts of add
(self, dst="", dev=None, verbose=conf.verb)
| 220 | self.ipv6_ifaces.add(iff) |
| 221 | |
| 222 | def route(self, dst="", dev=None, verbose=conf.verb): |
| 223 | # type: (str, Optional[str], int) -> Tuple[str, str, str] |
| 224 | """ |
| 225 | Provide best route to IPv6 destination address, based on Scapy |
| 226 | internal routing table content. |
| 227 | |
| 228 | When a set of address is passed (e.g. ``2001:db8:cafe:*::1-5``) an |
| 229 | address of the set is used. Be aware of that behavior when using |
| 230 | wildcards in upper parts of addresses ! |
| 231 | |
| 232 | If 'dst' parameter is a FQDN, name resolution is performed and result |
| 233 | is used. |
| 234 | |
| 235 | if optional 'dev' parameter is provided a specific interface, filtering |
| 236 | is performed to limit search to route associated to that interface. |
| 237 | """ |
| 238 | dst = dst or "::/0" # Enable route(None) to return default route |
| 239 | # Transform "2001:db8:cafe:*::1-5:0/120" to one IPv6 address of the set |
| 240 | dst = dst.split("/")[0] |
| 241 | savedst = dst # In case following inet_pton() fails |
| 242 | dst = dst.replace("*", "0") |
| 243 | idx = dst.find("-") |
| 244 | while idx >= 0: |
| 245 | m = (dst[idx:] + ":").find(":") |
| 246 | dst = dst[:idx] + dst[idx + m:] |
| 247 | idx = dst.find("-") |
| 248 | |
| 249 | try: |
| 250 | inet_pton(socket.AF_INET6, dst) |
| 251 | except socket.error: |
| 252 | dst = socket.getaddrinfo(savedst, None, socket.AF_INET6)[0][-1][0] |
| 253 | # TODO : Check if name resolution went well |
| 254 | |
| 255 | # Deal with dev-specific request for cache search |
| 256 | k = dst |
| 257 | if dev is not None: |
| 258 | k = dst + "%%" + dev |
| 259 | if k in self.cache: |
| 260 | return self.cache[k] |
| 261 | |
| 262 | paths = [] # type: List[Tuple[int, int, Tuple[str, List[str], str]]] |
| 263 | |
| 264 | # TODO : review all kinds of addresses (scope and *cast) to see |
| 265 | # if we are able to cope with everything possible. I'm convinced |
| 266 | # it's not the case. |
| 267 | # -- arnaud |
| 268 | for p, plen, gw, iface, cset, me in self.routes: |
| 269 | if dev is not None and iface != dev: |
| 270 | continue |
| 271 | if in6_isincluded(dst, p, plen): |
| 272 | paths.append((plen, me, (iface, cset, gw))) |
| 273 | elif (in6_ismlladdr(dst) and in6_islladdr(p) and in6_islladdr(cset[0])): # noqa: E501 |
| 274 | paths.append((plen, me, (iface, cset, gw))) |
| 275 | |
| 276 | if not paths: |
| 277 | if dst == "::1": |
| 278 | return (conf.loopback_name, "::1", "::") |
| 279 | else: |
no test coverage detected