def getmacbyip(ip, chainCC=0):
    """Return MAC address corresponding to a given IP address"""
    if isinstance(ip, Net):
        ip = iter(ip).next()
    tmp = map(ord, inet_aton(ip))
    if (tmp[0] & 0xf0) == 0xe0:  # mcast @
        return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1] & 0x7f, tmp[2], tmp[3])
    iff, a, gw = conf.route.route(ip)
    if ((iff == LOOPBACK_NAME) or (ip == conf.route.get_if_bcast(iff))):
        return "ff:ff:ff:ff:ff:ff"
    # Windows uses local IP instead of 0.0.0.0 to represent locally reachable addresses
    ifip = str(pcapdnet.dnet.intf().get(iff)['addr'])
    if gw != ifip.split('/')[0]:
        ip = gw

    mac = conf.netcache.arp_cache.get(ip)
    if mac:
        return mac

    res = srp1(Ether(dst=ETHER_BROADCAST) / ARP(op="who-has", pdst=ip),
               type=ETH_P_ARP,
               iface=iff,
               timeout=2,
               verbose=0,
               chainCC=chainCC,
               nofilter=1)
    if res is not None:
        mac = res.payload.hwsrc
        conf.netcache.arp_cache[ip] = mac
        return mac
    return None
Exemplo n.º 2
0
    def _get_gw_mac_address(self, gw_ip: str) -> str:
        try:
            self.logger.debug("sending arp for IP: %s ovs egress: %s",
                              gw_ip, self.config.non_nat_arp_egress_port)
            eth_mac_src = get_if_hwaddr(self.config.non_nat_arp_egress_port)

            pkt = Ether(dst=ETHER_BROADCAST, src=eth_mac_src)
            pkt /= ARP(op="who-has", pdst=gw_ip, hwsrc=eth_mac_src, psrc="0.0.0.0")
            self.logger.debug("pkt: %s", pkt.summary())

            res = srp1(pkt,
                       type=ETH_P_ARP,
                       iface=self.config.non_nat_arp_egress_port,
                       timeout=1,
                       verbose=0,
                       nofilter=1,
                       promisc=0)

            if res is not None:
                self.logger.debug("resp: %s ", res.summary())
                mac = res[ARP].hwsrc
                return mac
            else:
                self.logger.debug("Got Null response")

        except Scapy_Exception as ex:
            self.logger.warning("Error in probing Mac address: err %s", ex)
            return None
Exemplo n.º 3
0
def is_promisc(ip, fake_bcast="ff:ff:00:00:00:00", **kargs):
    # type: (str, str, **Any) -> bool
    """Try to guess if target is in Promisc mode. The target is provided by its ip."""  # noqa: E501

    responses = srp1(Ether(dst=fake_bcast) / ARP(op="who-has", pdst=ip), type=ETH_P_ARP, iface_hint=ip, timeout=1, verbose=0, **kargs)  # noqa: E501

    return responses is not None
Exemplo n.º 4
0
def getmacbyip(ip, chainCC=0):
    # type: (str, int) -> Optional[str]
    """Return MAC address corresponding to a given IP address"""
    if isinstance(ip, Net):
        ip = next(iter(ip))
    ip = inet_ntoa(inet_aton(ip or "0.0.0.0"))
    tmp = [orb(e) for e in inet_aton(ip)]
    if (tmp[0] & 0xf0) == 0xe0:  # mcast @
        return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1] & 0x7f, tmp[2], tmp[3])
    iff, _, gw = conf.route.route(ip)
    if (iff == conf.loopback_name) or (ip in conf.route.get_if_bcast(iff)):
        return "ff:ff:ff:ff:ff:ff"
    if gw != "0.0.0.0":
        ip = gw

    mac = _arp_cache.get(ip)
    if mac:
        return mac

    try:
        res = srp1(Ether(dst=ETHER_BROADCAST) / ARP(op="who-has", pdst=ip),
                   type=ETH_P_ARP,
                   iface=iff,
                   timeout=2,
                   verbose=0,
                   chainCC=chainCC,
                   nofilter=1)
    except Exception as ex:
        warning("getmacbyip failed on %s", ex)
        return None
    if res is not None:
        mac = res.payload.hwsrc
        _arp_cache[ip] = mac
        return mac
    return None
Exemplo n.º 5
0
def getmacbyip(ip, chainCC=0):
    """Return MAC address corresponding to a given IP address"""
    if isinstance(ip,Net):
        ip = iter(ip).next()
    tmp = map(ord, inet_aton(ip))
    if (tmp[0] & 0xf0) == 0xe0: # mcast @
        return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1]&0x7f,tmp[2],tmp[3])
    iff,a,gw = conf.route.route(ip)
    if ( (iff == LOOPBACK_NAME) or (ip == conf.route.get_if_bcast(iff)) ):
        return "ff:ff:ff:ff:ff:ff"
    # Windows uses local IP instead of 0.0.0.0 to represent locally reachable addresses
    ifip = str(pcapdnet.dnet.intf().get(iff)['addr'])
    if gw != ifip.split('/')[0]:
        ip = gw

    mac = conf.netcache.arp_cache.get(ip)
    if mac:
        return mac

    res = srp1(Ether(dst=ETHER_BROADCAST)/ARP(op="who-has", pdst=ip),
               type=ETH_P_ARP,
               iface = iff,
               timeout=2,
               verbose=0,
               chainCC=chainCC,
               nofilter=1)
    if res is not None:
        mac = res.payload.hwsrc
        conf.netcache.arp_cache[ip] = mac
        return mac
    return None
Exemplo n.º 6
0
def getmacbyip(ip, chainCC=0):
    """Return MAC address corresponding to a given IP address"""
    if isinstance(ip, Net):
        ip = next(iter(ip))
    ip = inet_ntoa(inet_aton(ip))
    tmp = [orb(e) for e in inet_aton(ip)]
    if (tmp[0] & 0xf0) == 0xe0:  # mcast @
        return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1] & 0x7f, tmp[2], tmp[3])
    iff, _, gw = conf.route.route(ip)
    if ((iff == consts.LOOPBACK_INTERFACE)
            or (ip == conf.route.get_if_bcast(iff))):  # noqa: E501
        return "ff:ff:ff:ff:ff:ff"
    if gw != "0.0.0.0":
        ip = gw

    mac = conf.netcache.arp_cache.get(ip)
    if mac:
        return mac

    res = srp1(Ether(dst=ETHER_BROADCAST) / ARP(op="who-has", pdst=ip),
               type=ETH_P_ARP,
               iface=iff,
               timeout=2,
               verbose=0,
               chainCC=chainCC,
               nofilter=1)
    if res is not None:
        mac = res.payload.hwsrc
        conf.netcache.arp_cache[ip] = mac
        return mac
    return None
Exemplo n.º 7
0
 def _do_request_lease(self, mac_address, ip=None, timeout_sec=10):
     logging.debug(
         f"Requesting lease for mac {mac_address} ip {ip} iface {self._net_iface}"
     )
     mac_raw = codecs.decode(mac_address.replace(':', ''), 'hex')
     if ip is None:
         broadcast_flag = scapy.fields.FlagValue(0b1000000000000000,
                                                 "???????????????B")
         dhcp_discover = l2.Ether(src=self._real_mac, dst='ff:ff:ff:ff:ff:ff') / \
                         inet.IP(src='0.0.0.0', dst='255.255.255.255') / \
                         inet.UDP(dport=67, sport=68) / \
                         dhcp.BOOTP(chaddr=mac_raw, xid=scapy.volatile.RandInt(), flags=broadcast_flag) / dhcp.DHCP(options=[('message-type', 'discover'), 'end'])
         dhcp_offer = sendrecv.srp1(dhcp_discover,
                                    iface=self._net_iface,
                                    verbose=self._verbose,
                                    timeout=timeout_sec)
         if dhcp_offer is None:
             raise TimeoutError(
                 f"Timeout. failed to get offer for mac {mac_address} iface: {self._net_iface}"
             )
         ip = dhcp_offer[dhcp.BOOTP].yiaddr
         server_id = DHCPRequestor._server_id_from_offer(
             dhcp_offer[dhcp.BOOTP])
         xid_cookie = dhcp_offer[dhcp.BOOTP].xid
     else:
         server_id = None
         xid_cookie = 0
     return self._dhcp_request(mac_raw,
                               ip,
                               xid_cookie,
                               server_id,
                               timeout_sec=timeout_sec)
Exemplo n.º 8
0
Arquivo: l2.py Projeto: 0x0mar/zarp
def getmacbyip(ip, chainCC=0):
    """Return MAC address corresponding to a given IP address"""
    if isinstance(ip,Net):
        ip = iter(ip).next()
    tmp = map(ord, inet_aton(ip))
    if (tmp[0] & 0xf0) == 0xe0: # mcast @
        return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1]&0x7f,tmp[2],tmp[3])
    iff,a,gw = conf.route.route(ip)
    if ( (iff == "lo") or (ip == conf.route.get_if_bcast(iff)) ):
        return "ff:ff:ff:ff:ff:ff"
    if gw != "0.0.0.0":
        ip = gw

    mac = conf.netcache.arp_cache.get(ip)
    if mac:
        return mac

    res = srp1(Ether(dst=ETHER_BROADCAST)/ARP(op="who-has", pdst=ip),
               type=ETH_P_ARP,
               iface = iff,
               timeout=2,
               verbose=0,
               chainCC=chainCC,
               nofilter=1)
    if res is not None:
        mac = res.payload.hwsrc
        conf.netcache.arp_cache[ip] = mac
        return mac
    return None
Exemplo n.º 9
0
Arquivo: l2.py Projeto: commial/scapy
def getmacbyip(ip, chainCC=0):
    """Return MAC address corresponding to a given IP address"""
    if isinstance(ip, Net):
        ip = next(iter(ip))
    ip = inet_ntoa(inet_aton(ip or "0.0.0.0"))
    tmp = [orb(e) for e in inet_aton(ip)]
    if (tmp[0] & 0xf0) == 0xe0:  # mcast @
        return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1] & 0x7f, tmp[2], tmp[3])
    iff, _, gw = conf.route.route(ip)
    if ((iff == consts.LOOPBACK_INTERFACE) or (ip == conf.route.get_if_bcast(iff))):  # noqa: E501
        return "ff:ff:ff:ff:ff:ff"
    if gw != "0.0.0.0":
        ip = gw

    mac = conf.netcache.arp_cache.get(ip)
    if mac:
        return mac

    try:
        res = srp1(Ether(dst=ETHER_BROADCAST) / ARP(op="who-has", pdst=ip),
                   type=ETH_P_ARP,
                   iface=iff,
                   timeout=2,
                   verbose=0,
                   chainCC=chainCC,
                   nofilter=1)
    except Exception:
        return None
    if res is not None:
        mac = res.payload.hwsrc
        conf.netcache.arp_cache[ip] = mac
        return mac
    return None
Exemplo n.º 10
0
Arquivo: l2.py Projeto: Osso/scapy
def is_promisc(ip, fake_bcast="ff:ff:00:00:00:00", **kargs):
    """Try to guess if target is in Promisc mode. The target is provided by its ip."""

    responses = srp1(Ether(dst=fake_bcast) / ARP(op="who-has", pdst=ip),
                     type=ETH_P_ARP, iface_hint=ip, timeout=1, verbose=0, **kargs)

    return responses is not None
Exemplo n.º 11
0
 def Checkpacket(self,PortType,Ethertype):
         print "======Checkpacket====="
         time.sleep(1)
         parameters = PubReadConfig("")
         mgmtmac = str(parameters.GetParameter("PC","MGMTMAC"))
         mgmtip = str(parameters.GetParameter("PC","MGMTIP"))
         dstip = str(parameters.GetParameter("DUT1","IP"))
         mgmtnic = str(parameters.GetParameter("PC","MGMTNIC"))
         if PortType == "Unaware":
             eth = Ether(src=mgmtmac,type=0x0806,dst="ff:ff:ff:ff:ff:ff")
             arp = ARP(hwtype=0x0001,ptype=0x0800,op=0x0001,hwsrc=mgmtmac,psrc="192.168.1.42",pdst=dstip,hwdst="ff:ff:ff:ff:ff:ff")
             a = eth/arp
         else:
             eth = Ether(src=mgmtmac,type=Ethertype,dst="ff:ff:ff:ff:ff:ff")
             priority = random.randint(0,7)
             dot1q=Dot1Q(type=0x0806,prio=priority,vlan=1)
             arp = ARP(hwtype=0x0001,ptype=0x0800,op=0x0001,hwsrc=mgmtmac,psrc="192.168.1.42",pdst=dstip,hwdst="ff:ff:ff:ff:ff:ff")
             a = eth/dot1q/arp
         os.system("ifconfig eth0 promisc")
         Reply = srp1(a,iface=mgmtnic,timeout=3)
         os.system("ifconfig eth0 -promisc")
         if Reply == None:
             return 0
         else:
             if Reply.op == 2:
                 return 1
             else:
                 return 0
Exemplo n.º 12
0
def dhcp_request(iface=None,**kargs):
    if conf.checkIPaddr != 0:
        warning("conf.checkIPaddr is not 0, I may not be able to match the answer")
    if iface is None:
        iface = conf.iface
    hw = get_if_raw_hwaddr(iface)
    return srp1(Ether(dst="ff:ff:ff:ff:ff:ff")/IP(src="0.0.0.0",dst="255.255.255.255")/UDP(sport=68,dport=67)
                 /BOOTP(chaddr=hw)/DHCP(options=[("message-type","discover"),"end"]),iface=iface,**kargs)
Exemplo n.º 13
0
Arquivo: dhcp.py Projeto: 0x0d/hijack
def dhcp_request(iface=None,**kargs):
    if conf.checkIPaddr != 0:
        warning("conf.checkIPaddr is not 0, I may not be able to match the answer")
    if iface is None:
        iface = conf.iface
    fam,hw = get_if_raw_hwaddr(iface)
    return srp1(Ether(dst="ff:ff:ff:ff:ff:ff")/IP(src="0.0.0.0",dst="255.255.255.255")/UDP(sport=68,dport=67)
                 /BOOTP(chaddr=hw)/DHCP(options=[("message-type","discover"),"end"]),iface=iface,**kargs)
Exemplo n.º 14
0
    def _get_gw_mac_address(self, ip: IPAddress, vlan: str = "") -> str:
        try:
            gw_ip = ipaddress.ip_address(ip.address)
            self.logger.debug("sending arp via egress: %s",
                              self.config.non_nat_arp_egress_port)
            eth_mac_src = get_if_hwaddr(self.config.non_nat_arp_egress_port)
            psrc = "0.0.0.0"
            egress_port_ip = get_if_addr(self.config.non_nat_arp_egress_port)
            if egress_port_ip:
                psrc = egress_port_ip

            pkt = Ether(dst=ETHER_BROADCAST, src=eth_mac_src)
            if vlan.isdigit():
                pkt /= Dot1Q(vlan=int(vlan))
            pkt /= ARP(op="who-has", pdst=gw_ip, hwsrc=eth_mac_src, psrc=psrc)
            self.logger.debug("ARP Req pkt %s", pkt.show(dump=True))

            res = srp1(pkt,
                       type=ETH_P_ALL,
                       iface=self.config.non_nat_arp_egress_port,
                       timeout=1,
                       verbose=0,
                       nofilter=1,
                       promisc=0)

            if res is not None:
                self.logger.debug("ARP Res pkt %s", res.show(dump=True))
                if str(res[ARP].psrc) != str(gw_ip):
                    self.logger.warning(
                        "Unexpected IP in ARP response. expected: %s pkt: %s",
                        str(gw_ip), res.show(dump=True))
                    return ""
                if vlan.isdigit():
                    if Dot1Q in res and str(res[Dot1Q].vlan) == vlan:
                        mac = res[ARP].hwsrc
                    else:
                        self.logger.warning(
                            "Unexpected vlan in ARP response. expected: %s pkt: %s",
                            vlan, res.show(dump=True))
                        return ""
                else:
                    mac = res[ARP].hwsrc
                return mac
            else:
                self.logger.debug("Got Null response")
                return ""

        except Scapy_Exception as ex:
            self.logger.warning("Error in probing Mac address: err %s", ex)
            return ""
        except ValueError:
            self.logger.warning("Invalid GW Ip address: [%s] or vlan %s",
                                str(ip), vlan)
            return ""
Exemplo n.º 15
0
def dhcp_request(iface=None, **kargs):
    """Send a DHCP discover request and return the answer"""
    if conf.checkIPaddr:
        warning(
            "conf.checkIPaddr is enabled, may not be able to match the answer"
        )
    if iface is None:
        iface = conf.iface
    fam, hw = get_if_raw_hwaddr(iface)
    return srp1(Ether(dst="ff:ff:ff:ff:ff:ff") / IP(src="0.0.0.0", dst="255.255.255.255") / UDP(sport=68, dport=67) /  # noqa: E501
                BOOTP(chaddr=hw) / DHCP(options=[("message-type", "discover"), "end"]), iface=iface, **kargs)  # noqa: E501
Exemplo n.º 16
0
def arp_scan():
    print("自动选取网段(注:如果机器存在多网段会选择错误网段),需手动修改IP")
    localnet = get_local()
    result = []
    for ipfix in range(1, 254):
        ip = '192.168.43' + "."+str(ipfix)
        #构造ARP包
        arppkt = Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=ip, hwdst="ff:ff:ff:ff:ff:ff")
        #发送并接受返回包
        res = srp1(arppkt, timeout=1, verbose=0)
        #print(res)
        if res:
            result.append(res.psrc)
            print("IP:"+res.psrc+"MAC:"+res.hwsrc)
        else:
            print("IP:"+ip+"!ARP扫描失败!")
Exemplo n.º 17
0
def get_response(url):
    """
    The function sends a dns request to 8.8.8.8 and prints the response
    :param url: the requested url to find
    :type url: str
    :return: None
    :rtype: None
    """
    ethmsg = Ether()
    ipmsg = IP(dst=DNS_IP)
    udpmsg = UDP(sport=SRC_PORT, dport=DNS_PORT)
    dnsmsg = DNS(rd=1, qd=DNSQR(qname=url))
    msg = ethmsg / ipmsg / udpmsg / dnsmsg
    ans = srp1(msg, verbose=0)
    print(ans.show())
    print("IP: " + ans[DNS][DNSRR].rdata)
Exemplo n.º 18
0
def dns_lookup(url):
    """
    The function sends a dns request to 8.8.8.8 and prints the response
    :param url: the requested url to find
    :type url: str
    :return: None
    :rtype: None
    """
    ethmsg = Ether()
    ipmsg = IP(dst=DNS_IP)
    udpmsg = UDP(sport=SRC_PORT, dport=DNS_PORT)
    dnsmsg = DNS(rd=1, qd=DNSQR(qname=url))
    msg = ethmsg / ipmsg / udpmsg / dnsmsg
    ans = srp1(msg, verbose=0)
    t = datetime.now().microsecond
    return ans[DNS][DNSRR].rdata
Exemplo n.º 19
0
def get_mac_by_yoip(yoip, chain_cc=0):
    """Return MAC address corresponding to a given YOIP address"""

    # TODO: is 0.0.0.0 a good enough default? I think so.
    iff, a, gw = conf.route.route("0.0.0.0")

    src_mac = get_if_hwaddr(iff)

    try:
        myyoip = conf.yoip
    except:
        myyoip = None

    if myyoip == yoip:
        return src_mac

    if yoip == "0.0":
        return "00:00:00:00:00:00"

    if yoip == "255.255":
        return "ff:ff:ff:ff:ff:ff"

    mac = conf.netcache.yoarp_cache.get(yoip)
    if mac:
        return mac

    print "GETTING MAC BY IP"

    pkt = (
        Ether(src=src_mac, dst=ETHER_BROADCAST) /
        YOARP(op="who-has", hwsrc=src_mac, psrc=conf.yoip, pdst=yoip)
    )
    # TODO: Do we need to fix anything in "answers"?

    res = srp1(pkt,
               iface=iff,
               timeout=5,
               verbose=0,
               retry=3,
               chainCC=chain_cc,
               nofilter=1)

    if res is not None:
        mac = res.payload.hwsrc
        conf.netcache.yoarp_cache[yoip] = mac
        return mac
Exemplo n.º 20
0
    def arp_scan(self,ip):

        for ipFix in range(1, 255 + 1):
            # 构造本网段的ip。如:192.168.50.20

            # 组合协议包
            # 通过 '/' 可叠加多个协议层(左底层到右上层),如Ether()/IP()/UDP()/DNS()
            arpPkt = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=ip)
            # 发送arp请求,并获取响应结果。设置1s超时。
            res = srp1(arpPkt, timeout=1, verbose=0)

            # 如果ip存活
            if res:
                return  1

            # 如果ip不存活
            else:
                return  0
def get_vlan_ip_and_mac(start=0, stop=255):
    # result = []
    for ipFix in range(start, stop):
        ip = localnet + "." + str(ipFix)
        # print(str(ip))
        # 组合协议包
        arpPkt = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=ip)
        res = srp1(arpPkt, timeout=5, verbose=0)
        # print(res)
        if res:
            # result.append({"localIP": res.psrc, "mac": res.hwsrc})
            mac = str(res.hwsrc).upper()
            macr = mac.replace(':', '-')
            result = Get_Organization.get_mac_organization(macr)
            organization = result[0]
            addr = result[1]
            print("IP:" + res.psrc + "\nMAC:" + macr + "\nORGANIZATION:" + organization)  # + '\nADDRESS:' + addr)
            print('---------------------------------------------------------')
Exemplo n.º 22
0
    def resolve_mac(self, timeout=None, retries=None):
        if timeout is None:
            timeout = self.arp_timeout
        if retries is None:
            retries = self.arp_retries

        # TODO: randomize source
        resp = srp1(
            Ether() / ARP(pdst=str(self.ip)),
            retry=retries,
            timeout=timeout,
            iface=conf.iface,
        )
        if resp is None:
            raise AddressNotResolvedError(
                'failed to resolve {}'.format(self.ip)
            )
        else:
            self.mac = MAC(resp[ARP].hwsrc)
Exemplo n.º 23
0
    def send(self, p, recv=False):
        """Send out a packet and optionally read back a reply."""

        self.finalizePacket(p)
        #print(colorama.Fore.CYAN + "TX ---> " + p.summary()[11:])
        self.tc.append(p)
        if self.testmode:
            print repr(p)
            r = None
        elif not recv:
            sendp(p)
            r = None
        else:
            r = srp1(p, timeout=RECV_TIMEOUT)
            if r is None:
                raise WiExceptionTimeout("srp1() timeout exceeded!")
            else:
                #print(colorama.Fore.CYAN + 'RX <--- ' + r.summary())
                pass

        return r
Exemplo n.º 24
0
    def _get_gw_mac_address(self, ip: IPv4Address) -> str:
        try:
            gw_ip = ipaddress.ip_address(ip.address)
            self.logger.debug("sending arp via egress: %s",
                              self.config.non_nat_arp_egress_port)
            eth_mac_src = get_if_hwaddr(self.config.non_nat_arp_egress_port)
            psrc = "0.0.0.0"
            egress_port_ip = get_if_addr(self.config.non_nat_arp_egress_port)
            if egress_port_ip:
                psrc = egress_port_ip

            pkt = Ether(dst=ETHER_BROADCAST, src=eth_mac_src)
            pkt /= ARP(op="who-has", pdst=gw_ip, hwsrc=eth_mac_src, psrc=psrc)
            self.logger.debug("ARP Req pkt %s", pkt.show(dump=True))

            res = srp1(pkt,
                       type=ETH_P_ARP,
                       iface=self.config.non_nat_arp_egress_port,
                       timeout=1,
                       verbose=0,
                       nofilter=1,
                       promisc=0)

            if res is not None:
                self.logger.debug("ARP Res pkt %s", res.show(dump=True))
                mac = res[ARP].hwsrc
                return mac
            else:
                self.logger.debug("Got Null response")
                return ""

        except Scapy_Exception as ex:
            self.logger.warning("Error in probing Mac address: err %s", ex)
            return ""
        except ValueError:
            self.logger.warning("Invalid GW Ip address: [%s]", ip)
            return ""
Exemplo n.º 25
0
    def _dhcp_request(self,
                      mac_raw,
                      requested_ip,
                      xid_cookie=0,
                      server_id="0.0.0.0",
                      timeout_sec=10):
        logging.debug(
            f"Sending dhcp request for {requested_ip} cookie {xid_cookie} server id {server_id} net {self._net_iface}"
        )
        broadcast_flag = scapy.fields.FlagValue(0b1000000000000000,
                                                "???????????????B")

        dhcp_options = [("message-type", "request")]
        if server_id is not None:
            dhcp_options.append(("server_id", server_id))
        dhcp_options.extend([("requested_addr", requested_ip),
                             ("param_req_list", 0), "end"])

        dhcp_request = l2.Ether(src=self._real_mac, dst="ff:ff:ff:ff:ff:ff") / \
                        inet.IP(src="0.0.0.0", dst="255.255.255.255") / \
                        inet.UDP(sport=68, dport=67) / \
                        dhcp.BOOTP(chaddr=mac_raw, xid=xid_cookie, flags=broadcast_flag) / \
                        dhcp.DHCP(options=dhcp_options)

        # send request, wait for ack
        dhcp_reply = sendrecv.srp1(dhcp_request,
                                   iface=self._net_iface,
                                   verbose=self._verbose,
                                   timeout=timeout_sec)
        if dhcp_reply is None:
            raise TimeoutError(
                f"DHCP request timeout on net {self._net_iface}")
        reply = DHCPRequestor._dhcp_reply_info(dhcp_reply)
        if dhcp.DHCPTypes[reply['message-type']] != 'ack':
            raise Exception("Failed to get ack %s" % reply)
        return reply
def get_mac_by_ip(ip="192.168.0.1"):
    """通过 IP 获取对方 MAC"""
    answer = srp1(Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=ip), timeout=2)
    if answer is not None:
        return answer[Ether].src
    return ""