Send / Receive a rtnetlink request
(pkt: Packet)
| 703 | |
| 704 | |
| 705 | def _sr1_rtrequest(pkt: Packet) -> List[Packet]: |
| 706 | """ |
| 707 | Send / Receive a rtnetlink request |
| 708 | """ |
| 709 | # Create socket |
| 710 | sock = socket.socket( |
| 711 | socket.AF_NETLINK, |
| 712 | socket.SOCK_RAW | socket.SOCK_CLOEXEC, |
| 713 | socket.NETLINK_ROUTE, |
| 714 | ) |
| 715 | # Configure socket |
| 716 | sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 32768) |
| 717 | sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 1048576) |
| 718 | try: |
| 719 | sock.setsockopt(SOL_NETLINK, NETLINK_EXT_ACK, 1) |
| 720 | except OSError: |
| 721 | # Linux 4.12+ only |
| 722 | pass |
| 723 | sock.bind((0, 0)) # bind to kernel |
| 724 | try: |
| 725 | sock.setsockopt(SOL_NETLINK, NETLINK_GET_STRICT_CHK, 1) |
| 726 | except OSError: |
| 727 | # Linux 4.20+ only |
| 728 | pass |
| 729 | # Request routes |
| 730 | sock.send(bytes(rtmsghdrs(msgs=[pkt]))) |
| 731 | results: List[Packet] = [] |
| 732 | try: |
| 733 | while True: |
| 734 | msgs = rtmsghdrs(sock.recv(65535)) |
| 735 | if not msgs: |
| 736 | log_loading.warning("Failed to read the routes using RTNETLINK !") |
| 737 | return [] |
| 738 | for msg in msgs.msgs: |
| 739 | # Keep going until we find the end of the MULTI format |
| 740 | if not msg.nlmsg_flags.NLM_F_MULTI or msg.nlmsg_type == 3: |
| 741 | if msg.nlmsg_type == 3 and nlmsgerr in msg and msg.status != 0: |
| 742 | # NLMSG_DONE with errors |
| 743 | if msg.data and msg.data[0].rta_type == 1: |
| 744 | log_loading.debug( |
| 745 | "Scapy RTNETLINK error on %s: '%s'. Please report !", |
| 746 | pkt.sprintf("%nlmsg_type%"), |
| 747 | msg.data[0].rta_data.decode(), |
| 748 | ) |
| 749 | return [] |
| 750 | return results |
| 751 | results.append(msg) |
| 752 | finally: |
| 753 | sock.close() |
| 754 | |
| 755 | |
| 756 | def _get_ips(af_family=socket.AF_UNSPEC): |