예제 #1
0
파일: dhcp.py 프로젝트: John-Lin/nat
    def handle_dhcp_discover(self, dhcp_pkt, datapath, port):
        try:
            # Choose a IP form IP pool list
            client_ip_addr = str(self.ip_pool_list.pop())
            self.mac_to_client_ip[dhcp_pkt.chaddr] = client_ip_addr
        except IndexError:
            self.logger.info("EMPTY IP POOL")
            return

        # send dhcp_offer message.
        dhcp_offer_msg_type = '\x02'
        self.logger.info("Send DHCP message type %s" %
                         (self.dhcp_msg_type_code[ord(dhcp_offer_msg_type)]))

        msg_option = dhcp.option(tag=dhcp.DHCP_MESSAGE_TYPE_OPT,
                                 value=dhcp_offer_msg_type)
        options = dhcp.options(option_list=[msg_option])
        hlen = len(addrconv.mac.text_to_bin(dhcp_pkt.chaddr))

        dhcp_pkt = dhcp.dhcp(hlen=hlen,
                             op=dhcp.DHCP_BOOT_REPLY,
                             chaddr=dhcp_pkt.chaddr,
                             yiaddr=client_ip_addr,
                             giaddr=dhcp_pkt.giaddr,
                             xid=dhcp_pkt.xid,
                             options=options)

        self._send_dhcp_packet(datapath, dhcp_pkt, port)
예제 #2
0
파일: dhcp.py 프로젝트: rubiruchi/NatRouter
    def assemble_offer(self, pkt):
        disc_eth = pkt.get_protocol(ethernet.ethernet)
        disc_ipv4 = pkt.get_protocol(ipv4.ipv4)
        disc_udp = pkt.get_protocol(udp.udp)
        disc = dhcp.dhcp.parser(pkt[3])
        disc[0].options.option_list.remove(next(opt for opt in disc[0].options.option_list if opt.tag == 55))
        disc[0].options.option_list.remove(next(opt for opt in disc[0].options.option_list if opt.tag == 53))
        disc[0].options.option_list.remove(next(opt for opt in disc[0].options.option_list if opt.tag == 12))
        disc[0].options.option_list.insert(0, dhcp.option(tag=1, value=self.bin_netmask))
        disc[0].options.option_list.insert(0, dhcp.option(tag=3, value=self.bin_server))
        disc[0].options.option_list.insert(0, dhcp.option(tag=6, value=self.bin_dns))
        disc[0].options.option_list.insert(0, dhcp.option(tag=12, value=self.hostname))
        disc[0].options.option_list.insert(0, dhcp.option(tag=53, value='02'.decode('hex')))
        disc[0].options.option_list.insert(0, dhcp.option(tag=54, value=self.bin_server))

        offer_pkt = packet.Packet()
        offer_pkt.add_protocol(ethernet.ethernet(ethertype=disc_eth.ethertype, dst=disc_eth.src, src=self.hw_addr))
        offer_pkt.add_protocol(ipv4.ipv4(dst=disc_ipv4.dst, src=self.dhcp_server, proto=disc_ipv4.proto))
        offer_pkt.add_protocol(udp.udp(src_port=67,dst_port=68))
        offer_pkt.add_protocol(dhcp.dhcp(op=2, chaddr=disc_eth.src,
                                         siaddr=self.dhcp_server,
                                         boot_file=disc[0].boot_file,
                                         yiaddr=self.ip_addr,
                                         xid=disc[0].xid,
                                         options=disc[0].options))
        self.logger.info("ASSEMBLED OFFER: %s" % offer_pkt)
        return offer_pkt
예제 #3
0
    def assemble_ack(self, pkt):
        req_eth = pkt.get_protocol(ethernet.ethernet)
        req_ipv4 = pkt.get_protocol(ipv4.ipv4)
        req_udp = pkt.get_protocol(udp.udp)
        req = pkt.get_protocol(dhcp.dhcp)
        req.options.option_list.remove(
            next(opt for opt in req.options.option_list if opt.tag == 53))
        req.options.option_list.insert(
            0, dhcp.option(tag=51, value=bytes.fromhex('8640'.encode().hex())))
        req.options.option_list.insert(0, dhcp.option(tag=53,
                                                      value=bytes([5])))

        ack_pkt = packet.Packet()
        ack_pkt.add_protocol(
            ethernet.ethernet(ethertype=req_eth.ethertype,
                              dst=req_eth.src,
                              src=self.hw_addr))
        ack_pkt.add_protocol(
            ipv4.ipv4(dst=req_ipv4.dst,
                      src=self.dhcp_server,
                      proto=req_ipv4.proto))
        ack_pkt.add_protocol(udp.udp(src_port=67, dst_port=68))
        ack_pkt.add_protocol(
            dhcp.dhcp(op=2,
                      chaddr=req_eth.src,
                      siaddr=self.dhcp_server,
                      boot_file=req.boot_file,
                      yiaddr=self._cal_vm_ip(req),
                      xid=req.xid,
                      options=req.options))
        self.logger.info("ASSEMBLED ACK: %s" % ack_pkt)
        return ack_pkt
예제 #4
0
    def assemble_ack(self, pkt):
        req_eth = pkt.get_protocol(ethernet.ethernet)
        req_ipv4 = pkt.get_protocol(ipv4.ipv4)
        req_udp = pkt.get_protocol(udp.udp)
        req = dhcp.dhcp.parser(pkt[3])
        req[0].options.option_list.remove(
            next(opt for opt in req[0].options.option_list if opt.tag == 53))
        req[0].options.option_list.insert(0, dhcp.option(tag=51, value='8640'))
        req[0].options.option_list.insert(
            0, dhcp.option(tag=53, value='05'.decode('hex')))

        ack_pkt = packet.Packet()
        ack_pkt.add_protocol(
            ethernet.ethernet(ethertype=req_eth.ethertype,
                              dst=req_eth.src,
                              src=self.hw_addr))
        ack_pkt.add_protocol(
            ipv4.ipv4(dst=req_ipv4.dst,
                      src=self.dhcp_server,
                      proto=req_ipv4.proto))
        ack_pkt.add_protocol(udp.udp(src_port=67, dst_port=68))
        ack_pkt.add_protocol(
            dhcp.dhcp(op=2,
                      chaddr=req_eth.src,
                      siaddr=self.dhcp_server,
                      boot_file=req[0].boot_file,
                      yiaddr=self.ip_addr,
                      xid=req[0].xid,
                      options=req[0].options))
        self.logger.info("ASSEMBLED ACK: %s" % ack_pkt)
        return ack_pkt
예제 #5
0
    def assemble_ack(self, pkt):
        response_eth = pkt.get_protocol(ethernet.ethernet)
        response_ipv4 = pkt.get_protocol(ipv4.ipv4)
        response = pkt.get_protocol(dhcp.dhcp)
        response.options.option_list.remove(
            next(opt for opt in response.options.option_list if opt.tag == 53))
        response.options.option_list.insert(0, dhcp.option(tag=51, value=''))
        response.options.option_list.insert(0, dhcp.option(tag=53, value=""))

        ack_pkt = packet.Packet()
        ack_pkt.add_protocol(
            ethernet.ethernet(ethertype=response_eth.ethertype,
                              dst=response_eth.src,
                              src=""))
        ack_pkt.add_protocol(
            ipv4.ipv4(dst=response_ipv4.dst,
                      src=self.dhcp_server,
                      proto=response_ipv4.proto))
        ack_pkt.add_protocol(udp.udp(src_port=67, dst_port=68))
        ack_pkt.add_protocol(
            dhcp.dhcp(op=2,
                      chaddr=response_eth.src,
                      siaddr="dhcp_server",
                      boot_file=response.boot_file,
                      yiaddr="ip_addr",
                      xid=response.xid,
                      options=response.options))
        return ack_pkt
예제 #6
0
파일: dhcp.py 프로젝트: Robin131/NAT
    def handle_dhcp_discover(self, dhcp_pkt, datapath, port):
        try:
            # Choose a IP form IP pool list
            client_ip_addr = str(self.ip_pool_list.pop())
            self.mac_to_client_ip[dhcp_pkt.chaddr] = client_ip_addr
        except IndexError:
            self.logger.info("EMPTY IP POOL")
            return

        # send dhcp_offer message.
        dhcp_offer_msg_type = '\x02'
        self.logger.info("Send DHCP message type %s" %
                         (self.dhcp_msg_type_code[ord(dhcp_offer_msg_type)]))

        msg_option = dhcp.option(tag=dhcp.DHCP_MESSAGE_TYPE_OPT,
                                 value=dhcp_offer_msg_type)
        options = dhcp.options(option_list=[msg_option])
        hlen = len(addrconv.mac.text_to_bin(dhcp_pkt.chaddr))

        dhcp_pkt = dhcp.dhcp(hlen=hlen,
                             op=dhcp.DHCP_BOOT_REPLY,
                             chaddr=dhcp_pkt.chaddr,
                             yiaddr=client_ip_addr,
                             giaddr=dhcp_pkt.giaddr,
                             xid=dhcp_pkt.xid,
                             options=options)

        self._send_dhcp_packet(datapath, dhcp_pkt, port)
예제 #7
0
    def assemble_ack(self, pkt, chaddr):
        chaddr_yiaddr = self.get_ip(chaddr)
        req_eth = pkt.get_protocol(ethernet.ethernet)
        req_ipv4 = pkt.get_protocol(ipv4.ipv4)
        req_udp = pkt.get_protocol(udp.udp)
        req = pkt.get_protocol(dhcp.dhcp)
        req.options.option_list.remove(
            next(opt for opt in req.options.option_list if opt.tag == 53))
        req.options.option_list.insert(
            0, dhcp.option(tag=51, value=str.encode('8640')))
        req.options.option_list.insert(
            0, dhcp.option(tag=53, value=str.encode('\x05')))

        ack_pkt = packet.Packet()
        ack_pkt.add_protocol(
            ethernet.ethernet(ethertype=req_eth.ethertype,
                              dst=req_eth.src,
                              src=self.hw_addr))
        ack_pkt.add_protocol(
            ipv4.ipv4(dst=req_ipv4.dst,
                      src=self.dhcp_server,
                      proto=req_ipv4.proto))
        ack_pkt.add_protocol(udp.udp(src_port=67, dst_port=68))
        ack_pkt.add_protocol(
            dhcp.dhcp(op=2,
                      chaddr=req_eth.src,
                      siaddr=self.dhcp_server,
                      boot_file=req.boot_file,
                      yiaddr=chaddr_yiaddr,
                      xid=req.xid,
                      options=req.options))
        self.logger.debug("ASSEMBLED ACK")
        return ack_pkt
예제 #8
0
파일: dhcp.py 프로젝트: wuyouke/ryu-dhcp
    def assemble_offer(self, pkt):
        disc_eth = pkt.get_protocol(ethernet.ethernet)
        disc_ipv4 = pkt.get_protocol(ipv4.ipv4)
        disc_udp = pkt.get_protocol(udp.udp)
        disc = dhcp.dhcp.parser(pkt[3])
        disc[0].options.option_list.remove(next(opt for opt in disc[0].options.option_list if opt.tag == 55))
        disc[0].options.option_list.remove(next(opt for opt in disc[0].options.option_list if opt.tag == 53))
        disc[0].options.option_list.remove(next(opt for opt in disc[0].options.option_list if opt.tag == 12))
        disc[0].options.option_list.insert(0, dhcp.option(tag=1, value=self.bin_netmask))
        disc[0].options.option_list.insert(0, dhcp.option(tag=3, value=self.bin_server))
        disc[0].options.option_list.insert(0, dhcp.option(tag=6, value=self.bin_dns))
        disc[0].options.option_list.insert(0, dhcp.option(tag=12, value=self.hostname))
        disc[0].options.option_list.insert(0, dhcp.option(tag=53, value='02'.decode('hex')))
        disc[0].options.option_list.insert(0, dhcp.option(tag=54, value=self.bin_server))

        offer_pkt = packet.Packet()
        offer_pkt.add_protocol(ethernet.ethernet(ethertype=disc_eth.ethertype, dst=disc_eth.src, src=self.hw_addr))
        offer_pkt.add_protocol(ipv4.ipv4(dst=disc_ipv4.dst, src=self.dhcp_server, proto=disc_ipv4.proto))
        offer_pkt.add_protocol(udp.udp(src_port=67,dst_port=68))
        offer_pkt.add_protocol(dhcp.dhcp(op=2, chaddr=disc_eth.src,
                                         siaddr=self.dhcp_server,
                                         boot_file=disc[0].boot_file,
                                         yiaddr=self.ip_addr,
                                         xid=disc[0].xid,
                                         options=disc[0].options))
        self.logger.info("ASSEMBLED OFFER: %s" % offer_pkt)
        return offer_pkt
예제 #9
0
    def create_dhcp_ack(self, dhcp_packet, dp, port, dst_ip="255.255.255.255"):

        if self.temp_offered.get(dhcp_packet.xid) is None:
            return

        subnet_mask = self.space[dp.id].netmask
        yiaddr = self.temp_offered[dhcp_packet.xid]["yiaddr"]
        chaddr = self.temp_offered[dhcp_packet.xid]["chaddr"]

        # add new or update existing dhcp bindings
        # we remember only last used ip address
        self.database[chaddr] = yiaddr

        pkt = packet.Packet()
        dhcp_ack_msg_type = b"\x05"
        subnet_option = dhcp.option(
            tag=dhcp.DHCP_SUBNET_MASK_OPT,
            value=addrconv.ipv4.text_to_bin(subnet_mask),
        )

        time_option = dhcp.option(tag=dhcp.DHCP_IP_ADDR_LEASE_TIME_OPT,
                                  value=bytearray(self.LEASE_TIME_ACK))
        msg_option = dhcp.option(tag=dhcp.DHCP_MESSAGE_TYPE_OPT,
                                 value=dhcp_ack_msg_type)

        dhcp_server_option = dhcp.option(tag=dhcp.DHCP_SERVER_IDENTIFIER_OPT,
                                         value=bytearray(self._ip_to_int()))

        options = dhcp.options(option_list=[
            msg_option,
            time_option,
            subnet_option,
            dhcp_server_option,
        ])

        hlen = dhcp_packet.hlen
        dhcp_pkt = dhcp.dhcp(
            op=dhcp.DHCP_BOOT_REPLY,
            hlen=hlen,
            chaddr=dhcp_packet.chaddr,
            yiaddr=yiaddr,
            siaddr=self.DHCP_SERVER_IP,
            giaddr=dhcp_packet.giaddr,
            xid=dhcp_packet.xid,
            options=options,
        )

        pkt.add_protocol(
            ethernet.ethernet(ethertype=ether.ETH_TYPE_IP,
                              dst=chaddr,
                              src=self.DHCP_SERVER_MAC))
        pkt.add_protocol(
            ipv4.ipv4(dst=dst_ip, src=self.DHCP_SERVER_IP, proto=17))
        pkt.add_protocol(udp.udp(src_port=67, dst_port=68))
        pkt.add_protocol(dhcp_pkt)
        pkt.serialize()

        self.inject_packet(pkt, dp, port)
예제 #10
0
    def _send_dhcp_req_to_app(self, lport, options=None):
        req = dhcp.dhcp(op=dhcp.DHCP_DISCOVER,
                        chaddr='aa:aa:aa:aa:aa:aa',
                        options=dhcp.options(options))
        pkt = self._create_fake_empty_packet()
        dhcp_response_pkt = self.app._create_dhcp_response(
            pkt, req, dhcp.DHCP_OFFER, lport)

        return dhcp_response_pkt
예제 #11
0
파일: dhcps.py 프로젝트: xixi2/ryu_sdn
 def assemble_ack(self, pkt):
     #self.semaphore.acquire()
     #self.semaphore.release()
     req_eth = pkt.get_protocol(ethernet.ethernet)
     req_ipv4 = pkt.get_protocol(ipv4.ipv4)
     req_udp = pkt.get_protocol(udp.udp)
     req = pkt.get_protocol(dhcp.dhcp)
     req.options.option_list.remove(
         next(opt for opt in req.options.option_list if opt.tag == 53))
     req.options.option_list.insert(
         0, dhcp.option(tag=1, value=self.bin_netmask))
     req.options.option_list.insert(
         0, dhcp.option(tag=3, value=self.bin_server))
     req.options.option_list.insert(0, dhcp.option(tag=6,
                                                   value=self.bin_dns))
     # disc.options.option_list.insert(
     #     0, dhcp.option(tag=12, value=self.hostname))
     req.options.option_list.insert(
         0, dhcp.option(tag=51, value=struct.pack('!I', self.release_time)))
     req.options.option_list.insert(
         0, dhcp.option(tag=53, value=struct.pack('!B', 5)))
     # disc.options.option_list.insert(
     #     0, dhcp.option(tag=54, value=self.hostname))
     req.options.option_list.insert(
         0,
         dhcp.option(tag=58,
                     value=struct.pack('!I', self.release_time // 2)))
     req.options.option_list.insert(
         0,
         dhcp.option(tag=59,
                     value=struct.pack('!I', self.release_time * 7 // 8)))
     if req_eth.src not in self.ip_pool:
         return
     # print(req_eth.src,end=" ")
     # print(self.ip_pool[req_eth.src][2], time.perf_counter())
     self.ip_pool[req_eth.src][1] = time.perf_counter()
     ack_pkt = packet.Packet()
     ack_pkt.add_protocol(
         ethernet.ethernet(ethertype=req_eth.ethertype,
                           dst=req_eth.src,
                           src=self.hw_addr))
     ack_pkt.add_protocol(
         ipv4.ipv4(dst=req_ipv4.dst,
                   src=self.dhcp_server,
                   proto=req_ipv4.proto))
     ack_pkt.add_protocol(udp.udp(src_port=67, dst_port=68))
     ack_pkt.add_protocol(
         dhcp.dhcp(op=2,
                   chaddr=req_eth.src,
                   siaddr=self.dhcp_server,
                   boot_file=req.boot_file,
                   yiaddr=self.ip_pool[req_eth.src][0],
                   xid=req.xid,
                   options=req.options))
     self.host_check()
     # self.logger.info("ASSEMBLED ACK: %s" % ack_pkt)
     return ack_pkt
예제 #12
0
파일: dhcp.py 프로젝트: haidlir/SNHx
    def assemble_ack(cls, pkt, datapath, port):
        req_eth = pkt.get_protocol(ethernet.ethernet)
        req_ipv4 = pkt.get_protocol(ipv4.ipv4)
        req_udp = pkt.get_protocol(udp.udp)
        req = pkt.get_protocol(dhcp.dhcp)

        wanted_ip = cls.get_option_value(req, 50)
        src = req_eth.src
        got_ip = None
        if src in cls.wan_leases[datapath]:
            if wanted_ip != cls.wan_leases[datapath][src]:
                cls.wan_pool.append(cls.wan_leases[datapath][src])
                del cls.wan_leases[datapath][src]
            else:
                got_ip = cls.wan_leases[datapath][src]
        if got_ip is None:
            if src in cls.wan_offers[datapath]:
                if wanted_ip != cls.wan_offers[datapath][src]:
                    cls.wan_pool.append(cls.wan_offers[datapath][src])
                    del cls.wan_offers[datapath][src]
                else:
                    got_ip = cls.wan_offers[datapath][src]
        if got_ip is None:
            if wanted_ip in cls.wan_pool[datapath]:
                cls.wan_pool[datapath].remove(wanted_ip)
                got_ip = wanted_ip
        if got_ip is None:
            # cls.log.warn("%s asked for un-offered %s", src, wanted_ip)
            # cls.nak(event) # nak 
            return

        req.options.option_list.remove(next(opt for opt in req.options.option_list if opt.tag == 53))
        req.options.option_list.insert(0, dhcp.option(tag=1, value=cls.bin_netmask))
        req.options.option_list.insert(0, dhcp.option(tag=3, value=addrconv.ipv4.text_to_bin(cls.dhcp_server[datapath])))
        req.options.option_list.insert(0, dhcp.option(tag=6, value=cls.bin_dns))
        req.options.option_list.insert(0, dhcp.option(tag=51, value='8640'))
        req.options.option_list.insert(0, dhcp.option(tag=53, value='05'.decode('hex')))
        req.options.option_list.insert(0, dhcp.option(tag=54, value=addrconv.ipv4.text_to_bin(cls.dhcp_server[datapath])))

        ack_pkt = packet.Packet()
        ack_pkt.add_protocol(ethernet.ethernet(ethertype=req_eth.ethertype, dst=src, src=cls.hw_addr))
        ack_pkt.add_protocol(ipv4.ipv4(dst=req_ipv4.dst, src=cls.dhcp_server[datapath], proto=req_ipv4.proto))
        ack_pkt.add_protocol(udp.udp(src_port=67,dst_port=68))
        ack_pkt.add_protocol(dhcp.dhcp(op=2, chaddr=src,
                                       hlen=6, # salah di len
                                       siaddr=cls.dhcp_server[datapath],
                                       boot_file=req.boot_file,
                                       yiaddr=wanted_ip,
                                       xid=req.xid,
                                       options=req.options))
        # cls.logger.info("ASSEMBLED ACK: %s" % ack_pkt)


        # print(wanted_ip, src, datapath, port)
        cls.add_arp(wanted_ip, src, datapath, port)
        return ack_pkt
예제 #13
0
    def create_dhcp_offer(self,
                          dhcp_packet,
                          dp,
                          port,
                          dst_ip="255.255.255.255"):
        xid = dhcp_packet.xid  # transaction id

        chaddr = dhcp_packet.chaddr
        yiaddr = None

        previous_ip = self.database.get(chaddr)

        if previous_ip:
            if previous_ip in self.pools[dp.id]:
                self.pools[dp.id].remove(previous_ip)
                yiaddr = previous_ip
            else:
                yiaddr = self.pools[dp.id].pop(-1)
        else:
            yiaddr = self.pools[dp.id].pop(-1)

        self.temp_offered[xid] = {"chaddr": chaddr, "yiaddr": yiaddr}

        pkt = packet.Packet()
        dhcp_offer_msg_type = b"\x02"
        hlen = dhcp_packet.hlen

        msg_option = dhcp.option(tag=dhcp.DHCP_MESSAGE_TYPE_OPT,
                                 value=dhcp_offer_msg_type)

        dhcp_server_option = dhcp.option(tag=dhcp.DHCP_SERVER_IDENTIFIER_OPT,
                                         value=bytearray(self._ip_to_int()))
        options = dhcp.options(option_list=[msg_option, dhcp_server_option])

        pkt.add_protocol(
            ethernet.ethernet(ethertype=ether.ETH_TYPE_IP,
                              dst=chaddr,
                              src=self.DHCP_SERVER_MAC))

        pkt.add_protocol(
            ipv4.ipv4(dst=dst_ip, src=self.DHCP_SERVER_IP, proto=17))
        pkt.add_protocol(udp.udp(src_port=67, dst_port=68))
        pkt.add_protocol(
            dhcp.dhcp(
                hlen=hlen,
                op=dhcp.DHCP_BOOT_REPLY,
                yiaddr=yiaddr,
                siaddr=self.DHCP_SERVER_IP,
                xid=dhcp_packet.xid,
                giaddr=dhcp_packet.giaddr,
                chaddr=chaddr,
                options=options,
            ))
        pkt.serialize()
        self.inject_packet(pkt, dp, port)
예제 #14
0
    def _create_dhcp_ack(self, pkt, dhcp_packet, lport):
        pkt_ipv4 = pkt.get_protocol(ipv4.ipv4)
        pkt_ethernet = pkt.get_protocol(ethernet.ethernet)

        subnet = self._get_subnet_by_port(lport)
        if subnet is None:
            LOG.error(_LE("No subnet found for port <%s>") %
                      lport.get_id())
            return

        dns = self._get_dns_address_list_bin(subnet)
        host_routes = self._get_host_routes_list_bin(subnet, lport)
        dhcp_server_address = str(self._get_dhcp_server_address(subnet))
        gateway_address = self._get_port_gateway_address(subnet)
        netmask_bin = self._get_port_netmask(subnet).packed
        domain_name_bin = struct.pack('!256s', self.domain_name)
        lease_time_bin = struct.pack('!I', self.lease_time)
        option_list = [
            dhcp.option(dhcp.DHCP_MESSAGE_TYPE_OPT, b'\x05', 1),
            dhcp.option(dhcp.DHCP_SUBNET_MASK_OPT, netmask_bin, 4),
            dhcp.option(dhcp.DHCP_GATEWAY_ADDR_OPT, gateway_address.packed, 4),
            dhcp.option(dhcp.DHCP_IP_ADDR_LEASE_TIME_OPT,
                    lease_time_bin, 4),
            dhcp.option(dhcp.DHCP_DNS_SERVER_ADDR_OPT, dns, len(dns)),
            dhcp.option(DHCP_DOMAIN_NAME_OPT,
                    domain_name_bin,
                    len(self.domain_name)),
            dhcp.option(DHCP_CLASSLESS_ROUTE, host_routes, len(host_routes))]

        if self.advertise_mtu:
            intreface_mtu = self._get_port_mtu(lport)
            mtu_bin = struct.pack('!H', intreface_mtu)
            option_list.append(dhcp.option(
                                    DHCP_INTERFACE_MTU_OPT,
                                    mtu_bin,
                                    len(mtu_bin)))
        options = dhcp.options(option_list=option_list)
        dhcp_ack_pkt = ryu_packet.Packet()
        dhcp_ack_pkt.add_protocol(ethernet.ethernet(
                                                ethertype=ether.ETH_TYPE_IP,
                                                dst=pkt_ethernet.src,
                                                src=pkt_ethernet.dst))
        dhcp_ack_pkt.add_protocol(ipv4.ipv4(dst=pkt_ipv4.src,
                                  src=dhcp_server_address,
                                  proto=pkt_ipv4.proto))
        dhcp_ack_pkt.add_protocol(udp.udp(src_port=67, dst_port=68))
        dhcp_ack_pkt.add_protocol(dhcp.dhcp(op=2, chaddr=pkt_ethernet.src,
                                         siaddr=dhcp_server_address,
                                         boot_file=dhcp_packet.boot_file,
                                         yiaddr=lport.get_ip(),
                                         xid=dhcp_packet.xid,
                                         options=options))
        return dhcp_ack_pkt
예제 #15
0
    def _create_dhcp_ack(self, pkt, dhcp_packet, lport):
        pkt_ipv4 = pkt.get_protocol(ipv4.ipv4)
        pkt_ethernet = pkt.get_protocol(ethernet.ethernet)

        subnet = self._get_subnet_by_port(lport)
        if subnet is None:
            LOG.error(_LE("No subnet found for port <%s>") %
                      lport.get_id())
            return

        dns = self._get_dns_address_list_bin(subnet)
        host_routes = self._get_host_routes_list_bin(subnet)
        dhcp_server_address = str(self._get_dhcp_server_address(subnet))
        gateway_address = self._get_port_gateway_address(subnet)
        netmask_bin = self._get_port_netmask(subnet).packed
        domain_name_bin = struct.pack('!256s', self.domain_name)
        lease_time_bin = struct.pack('!I', self.lease_time)
        option_list = [
            dhcp.option(dhcp.DHCP_MESSAGE_TYPE_OPT, b'\x05', 1),
            dhcp.option(dhcp.DHCP_SUBNET_MASK_OPT, netmask_bin, 4),
            dhcp.option(dhcp.DHCP_GATEWAY_ADDR_OPT, gateway_address.packed, 4),
            dhcp.option(dhcp.DHCP_IP_ADDR_LEASE_TIME_OPT,
                    lease_time_bin, 4),
            dhcp.option(dhcp.DHCP_DNS_SERVER_ADDR_OPT, dns, len(dns)),
            dhcp.option(DHCP_DOMAIN_NAME_OPT,
                    domain_name_bin,
                    len(self.domain_name)),
            dhcp.option(DHCP_CLASSLESS_ROUTE, host_routes, len(host_routes))]

        if self.advertise_mtu:
            intreface_mtu = self._get_port_mtu(lport)
            mtu_bin = struct.pack('!H', intreface_mtu)
            option_list.append(dhcp.option(
                                    DHCP_INTERFACE_MTU_OPT,
                                    mtu_bin,
                                    len(mtu_bin)))
        options = dhcp.options(option_list=option_list)
        dhcp_ack_pkt = ryu_packet.Packet()
        dhcp_ack_pkt.add_protocol(ethernet.ethernet(
                                                ethertype=ether.ETH_TYPE_IP,
                                                dst=pkt_ethernet.src,
                                                src=pkt_ethernet.dst))
        dhcp_ack_pkt.add_protocol(ipv4.ipv4(dst=pkt_ipv4.src,
                                  src=dhcp_server_address,
                                  proto=pkt_ipv4.proto))
        dhcp_ack_pkt.add_protocol(udp.udp(src_port=67, dst_port=68))
        dhcp_ack_pkt.add_protocol(dhcp.dhcp(op=2, chaddr=pkt_ethernet.src,
                                         siaddr=dhcp_server_address,
                                         boot_file=dhcp_packet.boot_file,
                                         yiaddr=lport.get_ip(),
                                         xid=dhcp_packet.xid,
                                         options=options))
        return dhcp_ack_pkt
예제 #16
0
    def assemble_offer(self, pkt):
        disc_eth = pkt.get_protocol(ethernet.ethernet)
        disc_ipv4 = pkt.get_protocol(ipv4.ipv4)
        disc_udp = pkt.get_protocol(udp.udp)
        disc = pkt.get_protocol(dhcp.dhcp)
        #remove pkt.dhcp.option.option_list , tag = 55 (Parameter Request List)
        disc.options.option_list.remove(
            next(opt for opt in disc.options.option_list if opt.tag == 55))
        #remove pkt.dhcp.option.option_list , tag = 53 (DHCP Message Type)
        disc.options.option_list.remove(
            next(opt for opt in disc.options.option_list if opt.tag == 53))
        # remove pkt.dhcp.option.option_list , tag = 12 (Host Name)
        disc.options.option_list.remove(
            next(opt for opt in disc.options.option_list if opt.tag == 12))
        #insert pkt.dhcp.option.option_list , tag = 1 (Subnet Mask)
        disc.options.option_list.insert(0, dhcp.option(tag=1, value=""))
        # insert pkt.dhcp.option.option_list , tag = 3 (Router)
        disc.options.option_list.insert(0, dhcp.option(tag=3, value=""))
        # insert pkt.dhcp.option.option_list , tag = 6 (Domain Name Server 域名服务器)
        disc.options.option_list.insert(0, dhcp.option(tag=6, value=""))
        # insert pkt.dhcp.option.option_list , tag = 12 (Host Name)
        disc.options.option_list.insert(0, dhcp.option(tag=12, value=""))
        # insert pkt.dhcp.option.option_list , tag = 53 (DHCP Message Type)
        disc.options.option_list.insert(0, dhcp.option(tag=53, value=''))
        # insert pkt.dhcp.option.option_list , tag = 54 (Server Identifier)
        disc.options.option_list.insert(0, dhcp.option(tag=54, value=""))

        #Constructing a Packet
        offer_pkt = packet.Packet()
        #Packet protocol level one
        offer_pkt.add_protocol(
            ethernet.ethernet(ethertype=disc_eth.ethertype,
                              dst=disc_eth.src,
                              src=self.DHCP_MAC))
        #Packet protocol level two
        offer_pkt.add_protocol(
            ipv4.ipv4(dst=disc_ipv4.dst,
                      src=self.DHCP_server,
                      proto=disc_ipv4.proto))
        #Packet protocol level three
        offer_pkt.add_protocol(udp.udp(src_port=67, dst_port=68))
        #Packet protocol level four
        offer_pkt.add_protocol(
            dhcp.dhcp(op=2,
                      chaddr=disc_eth.src,
                      siaddr=self.DHCP_server,
                      boot_file=disc.boot_file,
                      yiaddr=self.ip_addr,
                      xid=disc.xid,
                      options=disc.options))
        return offer_pkt
예제 #17
0
    def _create_dhcp_offer(self, pkt, dhcp_packet, lport):
        pkt_ipv4 = pkt.get_protocol(ipv4.ipv4)
        pkt_ethernet = pkt.get_protocol(ethernet.ethernet)

        subnet = self._get_subnet_by_port(lport)
        if subnet is None:
            LOG.error(_LE("No subnet found for port <%s>") % lport.get_id())
            return

        dns = self._get_dns_address_list_bin(subnet)
        dhcp_server_address = self._get_dhcp_server_address(subnet)
        netmask_bin = self._get_port_netmask(subnet).packed
        lease_time_bin = struct.pack('!I', self.lease_time)
        gateway_address = self._get_port_gateway_address(subnet)
        domain_name_bin = struct.pack('!256s', self.domain_name)

        option_list = [
            dhcp.option(dhcp.DHCP_MESSAGE_TYPE_OPT, b'\x02', 1),
            dhcp.option(dhcp.DHCP_SUBNET_MASK_OPT, netmask_bin, 4),
            dhcp.option(dhcp.DHCP_DNS_SERVER_ADDR_OPT, dns, len(dns)),
            dhcp.option(dhcp.DHCP_IP_ADDR_LEASE_TIME_OPT, lease_time_bin, 4),
            dhcp.option(dhcp.DHCP_SERVER_IDENTIFIER_OPT,
                        dhcp_server_address.packed, 4),
            dhcp.option(15, domain_name_bin, len(self.domain_name))
        ]
        if gateway_address:
            option_list.append(
                dhcp.option(dhcp.DHCP_GATEWAY_ADDR_OPT, gateway_address.packed,
                            4))

        options = dhcp.options(option_list=option_list)
        dhcp_offer_pkt = ryu_packet.Packet()
        dhcp_offer_pkt.add_protocol(
            ethernet.ethernet(ethertype=ether.ETH_TYPE_IP,
                              dst=pkt_ethernet.src,
                              src=pkt_ethernet.dst))
        dhcp_offer_pkt.add_protocol(
            ipv4.ipv4(dst=pkt_ipv4.src,
                      src=str(dhcp_server_address),
                      proto=pkt_ipv4.proto))
        dhcp_offer_pkt.add_protocol(udp.udp(src_port=67, dst_port=68))
        dhcp_offer_pkt.add_protocol(
            dhcp.dhcp(op=2,
                      chaddr=pkt_ethernet.src,
                      siaddr=str(dhcp_server_address),
                      boot_file=dhcp_packet.boot_file,
                      yiaddr=lport.get_ip(),
                      xid=dhcp_packet.xid,
                      options=options))
        return dhcp_offer_pkt
예제 #18
0
파일: dhcp.py 프로젝트: haidlir/SNHx
    def assemble_offer(cls, pkt, datapath):
        disc_eth = pkt.get_protocol(ethernet.ethernet)
        disc_ipv4 = pkt.get_protocol(ipv4.ipv4)
        disc_udp = pkt.get_protocol(udp.udp)
        disc = pkt.get_protocol(dhcp.dhcp)

        src = disc_eth.src 
        if src in cls.wan_leases[datapath]:
            offer = cls.wan_leases[datapath][src]
            del cls.wan_leases[datapath][src]
            cls.wan_offers[datapath][src] = offer
        else:
            offer = cls.wan_offers[datapath].get(src)
            if offer is None:
                if len(cls.wan_pool[datapath]) == 0:
                    # cls.logger.error("Out of IP addresses")
                    # dhcp nak belum dibuat
                    # cls.nak(pkt)
                    return

                offer = cls.wan_pool[datapath][0]
                # jika request IP diminta belum dibuat
                cls.wan_pool[datapath].remove(offer)
                cls.wan_offers[datapath][src] = offer

        yiaddr = offer
        disc.options.option_list.remove(next(opt for opt in disc.options.option_list if opt.tag == 55))
        disc.options.option_list.remove(next(opt for opt in disc.options.option_list if opt.tag == 53))
        disc.options.option_list.remove(next(opt for opt in disc.options.option_list if opt.tag == 12))
        disc.options.option_list.insert(0, dhcp.option(tag=1, value=cls.bin_netmask))
        disc.options.option_list.insert(0, dhcp.option(tag=3, value=addrconv.ipv4.text_to_bin(cls.dhcp_server[datapath])))
        disc.options.option_list.insert(0, dhcp.option(tag=6, value=cls.bin_dns))
        # disc.options.option_list.insert(0, dhcp.option(tag=12, value=cls.hostname))
        disc.options.option_list.insert(0, dhcp.option(tag=53, value='02'.decode('hex')))
        disc.options.option_list.insert(0, dhcp.option(tag=54, value=addrconv.ipv4.text_to_bin(cls.dhcp_server[datapath])))

        offer_pkt = packet.Packet()
        offer_pkt.add_protocol(ethernet.ethernet(ethertype=disc_eth.ethertype, dst=src, src=cls.hw_addr))
        offer_pkt.add_protocol(ipv4.ipv4(dst=disc_ipv4.dst, src=cls.dhcp_server[datapath], proto=disc_ipv4.proto))
        offer_pkt.add_protocol(udp.udp(src_port=67,dst_port=68))
        offer_pkt.add_protocol(dhcp.dhcp(op=2, chaddr=src,
                                         hlen=6, # salah di len
                                         siaddr=cls.dhcp_server[datapath],
                                         boot_file=disc.boot_file,
                                         yiaddr=yiaddr,
                                         xid=disc.xid,
                                         options=disc.options))
        # cls.logger.info("ASSEMBLED OFFER: %s" % offer_pkt)
        return offer_pkt
예제 #19
0
    def _create_dhcp_offer(self, pkt, dhcp_packet, lport):
        pkt_ipv4 = pkt.get_protocol(ipv4.ipv4)
        pkt_ethernet = pkt.get_protocol(ethernet.ethernet)

        subnet = self._get_subnet_by_port(lport)
        if subnet is None:
            LOG.error(_LE("No subnet found for port <%s>") %
                      lport.get_id())
            return

        dns = self._get_dns_address_list_bin(subnet)
        dhcp_server_address = self._get_dhcp_server_address(subnet)
        netmask_bin = self._get_port_netmask(subnet).packed
        lease_time_bin = struct.pack('!I', self.lease_time)
        gateway_address = self._get_port_gateway_address(subnet)
        domain_name_bin = struct.pack('!256s', self.domain_name)

        option_list = [
            dhcp.option(dhcp.DHCP_MESSAGE_TYPE_OPT, b'\x02', 1),
            dhcp.option(dhcp.DHCP_SUBNET_MASK_OPT, netmask_bin, 4),
            dhcp.option(dhcp.DHCP_DNS_SERVER_ADDR_OPT, dns, len(dns)),
            dhcp.option(dhcp.DHCP_IP_ADDR_LEASE_TIME_OPT,
                        lease_time_bin, 4),
            dhcp.option(dhcp.DHCP_SERVER_IDENTIFIER_OPT,
                        dhcp_server_address.packed, 4),
            dhcp.option(15, domain_name_bin, len(self.domain_name))]
        if gateway_address:
            option_list.append(dhcp.option(
                                    dhcp.DHCP_GATEWAY_ADDR_OPT,
                                    gateway_address.packed,
                                    4))

        options = dhcp.options(option_list=option_list)
        dhcp_offer_pkt = ryu_packet.Packet()
        dhcp_offer_pkt.add_protocol(ethernet.ethernet(
                                    ethertype=ether.ETH_TYPE_IP,
                                    dst=pkt_ethernet.src,
                                    src=pkt_ethernet.dst))
        dhcp_offer_pkt.add_protocol(ipv4.ipv4(dst=pkt_ipv4.src,
                                   src=str(dhcp_server_address),
                                   proto=pkt_ipv4.proto))
        dhcp_offer_pkt.add_protocol(udp.udp(src_port=67, dst_port=68))
        dhcp_offer_pkt.add_protocol(dhcp.dhcp(op=2, chaddr=pkt_ethernet.src,
                                         siaddr=str(dhcp_server_address),
                                         boot_file=dhcp_packet.boot_file,
                                         yiaddr=lport.get_ip(),
                                         xid=dhcp_packet.xid,
                                         options=options))
        return dhcp_offer_pkt
예제 #20
0
    def _create_dhcp_response(self, packet, dhcp_request, response_type,
                              lport):
        pkt_ipv4 = packet.get_protocol(ipv4.ipv4)
        pkt_ethernet = packet.get_protocol(ethernet.ethernet)

        try:
            subnet = lport.subnets[0]
        except IndexError:
            LOG.warning("No subnet found for port %s", lport.id)
            return

        dhcp_server_address = subnet.dhcp_ip
        if not dhcp_server_address:
            LOG.warning("Could not find DHCP server address for subnet %s",
                        subnet.id)
            return

        option_list = self._build_dhcp_options(dhcp_request, response_type,
                                               lport, subnet,
                                               dhcp_server_address)

        options = dhcp.options(option_list=option_list)

        dhcp_server_address = subnet.dhcp_ip
        dhcp_response = ryu_packet.Packet()
        dhcp_response.add_protocol(
            ethernet.ethernet(ethertype=ether.ETH_TYPE_IP,
                              dst=pkt_ethernet.src,
                              src=pkt_ethernet.dst))
        dhcp_response.add_protocol(
            ipv4.ipv4(dst=pkt_ipv4.src,
                      src=dhcp_server_address,
                      proto=pkt_ipv4.proto))
        dhcp_response.add_protocol(
            udp.udp(src_port=const.DHCP_SERVER_PORT,
                    dst_port=const.DHCP_CLIENT_PORT))

        siaddr = lport.dhcp_params.siaddr or dhcp_server_address

        dhcp_response.add_protocol(
            dhcp.dhcp(op=dhcp.DHCP_BOOT_REPLY,
                      chaddr=pkt_ethernet.src,
                      siaddr=siaddr,
                      boot_file=dhcp_request.boot_file,
                      yiaddr=lport.ip,
                      xid=dhcp_request.xid,
                      options=options))
        return dhcp_response
예제 #21
0
    def assemble_offer(self, pkt, datapath):
        disc_eth = pkt.get_protocol(ethernet.ethernet)
        disc_ipv4 = pkt.get_protocol(ipv4.ipv4)
        disc = pkt.get_protocol(dhcp.dhcp)
        offer_pkt = None
        ipaddress, netmask, address, dhcpip = self.get_server_info(datapath)
        hostipaddress, hostname, dns = self.get_host_info(
            datapath, disc_eth.src)
        
        if ipaddress:
            disc.options.option_list.remove(
                next(opt for opt in disc.options.option_list if opt.tag == 55))
            disc.options.option_list.remove(
                next(opt for opt in disc.options.option_list if opt.tag == 53))
            disc.options.option_list.remove(
                next(opt for opt in disc.options.option_list if opt.tag == 12))
            disc.options.option_list.insert(
                0, dhcp.option(tag=1, value=netmask))
            disc.options.option_list.insert(
                0, dhcp.option(tag=3, value=ipaddress))
            disc.options.option_list.insert(
                0, dhcp.option(tag=6, value=dns))
            disc.options.option_list.insert(
                0, dhcp.option(tag=12, value=hostname))
            disc.options.option_list.insert(
                0, dhcp.option(tag=53, value='02'.decode('hex')))
            disc.options.option_list.insert(
                0, dhcp.option(tag=54, value=ipaddress))
            offer_pkt = packet.Packet()
            offer_pkt.add_protocol(ethernet.ethernet(
                ethertype=disc_eth.ethertype, dst=disc_eth.src, src=address))
            offer_pkt.add_protocol(
                ipv4.ipv4(dst=disc_ipv4.dst, src=dhcpip, proto=disc_ipv4.proto))
            offer_pkt.add_protocol(udp.udp(src_port=67, dst_port=68))
            offer_pkt.add_protocol(dhcp.dhcp(op=2, chaddr=disc_eth.src,
                                             siaddr=dhcpip,
                                             boot_file=disc.boot_file,
                                             yiaddr=hostipaddress[:-3],   # to remove /24
                                             xid=disc.xid,
                                             options=disc.options))

            self.logger.info("ASSEMBLED OFFER: %s --> %s" %
                             (disc_eth.src, hostipaddress))

        return offer_pkt
예제 #22
0
    def assemble_ack(self, pkt, datapath):
        req_eth = pkt.get_protocol(ethernet.ethernet)
        req_ipv4 = pkt.get_protocol(ipv4.ipv4)
        req = pkt.get_protocol(dhcp.dhcp)

        ipaddress, netmask, address, dhcpip = self.get_server_info(datapath)
        hostipaddress, hostname, dns = self.get_host_info(datapath,
                                                          req_eth.src)
        
        if ipaddress:
            req.options.option_list.remove(
                next(opt for opt in req.options.option_list if opt.tag == 53))
            req.options.option_list.insert(
                0, dhcp.option(tag=51, value='8640'))
            req.options.option_list.insert(
                0, dhcp.option(tag=1, value=netmask))
            req.options.option_list.insert(
                0, dhcp.option(tag=3, value=ipaddress))
            req.options.option_list.insert(
                0, dhcp.option(tag=6, value=dns))
            req.options.option_list.insert(
                0, dhcp.option(tag=12, value=hostname))
            req.options.option_list.insert(
                0, dhcp.option(tag=54, value=ipaddress))
            req.options.option_list.insert(
                0, dhcp.option(tag=53, value='05'.decode('hex')))

            ack_pkt = packet.Packet()
            ack_pkt.add_protocol(ethernet.ethernet(
                ethertype=req_eth.ethertype, dst=req_eth.src, src=address))
            ack_pkt.add_protocol(
                ipv4.ipv4(dst=req_ipv4.dst, src=dhcpip, proto=req_ipv4.proto))
            ack_pkt.add_protocol(udp.udp(src_port=67, dst_port=68))
            ack_pkt.add_protocol(dhcp.dhcp(op=2, chaddr=req_eth.src,
                                           siaddr=dhcpip,
                                           boot_file=req.boot_file,
                                           yiaddr=hostipaddress[:-3],  # to remove /24
                                           xid=req.xid,
                                           options=req.options))
            self.logger.info("ASSEMBLED ACK: %s -> %s" %
                             (req_eth.src, hostipaddress))
        return ack_pkt
예제 #23
0
파일: dhcp.py 프로젝트: wuyouke/ryu-dhcp
    def assemble_ack(self, pkt):
        req_eth = pkt.get_protocol(ethernet.ethernet)
        req_ipv4 = pkt.get_protocol(ipv4.ipv4)
        req_udp = pkt.get_protocol(udp.udp)
        req = dhcp.dhcp.parser(pkt[3])
        req[0].options.option_list.remove(next(opt for opt in req[0].options.option_list if opt.tag == 53))
        req[0].options.option_list.insert(0, dhcp.option(tag=51, value='8640'))
        req[0].options.option_list.insert(0, dhcp.option(tag=53, value='05'.decode('hex')))

        ack_pkt = packet.Packet()
        ack_pkt.add_protocol(ethernet.ethernet(ethertype=req_eth.ethertype, dst=req_eth.src, src=self.hw_addr))
        ack_pkt.add_protocol(ipv4.ipv4(dst=req_ipv4.dst, src=self.dhcp_server, proto=req_ipv4.proto))
        ack_pkt.add_protocol(udp.udp(src_port=67,dst_port=68))
        ack_pkt.add_protocol(dhcp.dhcp(op=2, chaddr=req_eth.src,
                                       siaddr=self.dhcp_server,
                                       boot_file=req[0].boot_file,
                                       yiaddr=self.ip_addr,
                                       xid=req[0].xid,
                                       options=req[0].options))
        self.logger.info("ASSEMBLED ACK: %s" % ack_pkt)
        return ack_pkt
예제 #24
0
파일: dhcp.py 프로젝트: Robin131/NAT
    def handle_dhcp_request(self, dhcp_pkt, datapath, port):
        # send dhcp_ack message.
        dhcp_ack_msg_type = '\x05'
        self.logger.info("Send DHCP message type %s" %
                         (self.dhcp_msg_type_code[ord(dhcp_ack_msg_type)]))

        subnet_option = dhcp.option(tag=dhcp.DHCP_SUBNET_MASK_OPT,
                                    value=addrconv.ipv4.text_to_bin(
                                        self.ip_network.netmask))
        gw_option = dhcp.option(tag=dhcp.DHCP_GATEWAY_ADDR_OPT,
                                value=addrconv.ipv4.text_to_bin(self.gw_addr))
        dns_option = dhcp.option(tag=dhcp.DHCP_DNS_SERVER_ADDR_OPT,
                                 value=addrconv.ipv4.text_to_bin(
                                     self.dns_addr))
        time_option = dhcp.option(tag=dhcp.DHCP_IP_ADDR_LEASE_TIME_OPT,
                                  value='\xFF\xFF\xFF\xFF')
        msg_option = dhcp.option(tag=dhcp.DHCP_MESSAGE_TYPE_OPT,
                                 value=dhcp_ack_msg_type)
        id_option = dhcp.option(tag=dhcp.DHCP_SERVER_IDENTIFIER_OPT,
                                value=addrconv.ipv4.text_to_bin(
                                    self.dhcp_addr))

        options = dhcp.options(option_list=[
            msg_option, id_option, time_option, subnet_option, gw_option,
            dns_option
        ])
        hlen = len(addrconv.mac.text_to_bin(dhcp_pkt.chaddr))

        # Look up IP by using client mac address
        client_ip_addr = self.mac_to_client_ip[dhcp_pkt.chaddr]

        dhcp_pkt = dhcp.dhcp(op=dhcp.DHCP_BOOT_REPLY,
                             hlen=hlen,
                             chaddr=dhcp_pkt.chaddr,
                             yiaddr=client_ip_addr,
                             giaddr=dhcp_pkt.giaddr,
                             xid=dhcp_pkt.xid,
                             options=options)

        self._send_dhcp_packet(datapath, dhcp_pkt, port)
예제 #25
0
    def assemble_ack(self, pkt):
        req_eth = pkt.get_protocol(ethernet.ethernet)
        req_ipv4 = pkt.get_protocol(ipv4.ipv4)
        req_udp = pkt.get_protocol(udp.udp)
        req = pkt.get_protocol(dhcp.dhcp)
        if not (self.networkMap.findActiveHostByMac(req_eth.src)):
            return
        req.options.option_list.remove(
            next(opt for opt in req.options.option_list if opt.tag == 53))
        req.options.option_list.insert(0, dhcp.option(tag=51, value='8640'))
        req.options.option_list.insert(
            0, dhcp.option(tag=53, value='05'.decode('hex')))
        req.options.option_list.insert(
            0, dhcp.option(tag=1, value=self.bin_netmask))
        req.options.option_list.insert(
            0, dhcp.option(tag=3, value=self.bin_server))
        req.options.option_list.insert(0, dhcp.option(tag=6,
                                                      value=self.bin_dns))

        ack_pkt = packet.Packet()
        ack_pkt.add_protocol(
            ethernet.ethernet(ethertype=req_eth.ethertype,
                              dst=req_eth.src,
                              src=self.hw_addr))
        ack_pkt.add_protocol(
            ipv4.ipv4(dst=req_ipv4.dst,
                      src=self.dhcp_server,
                      proto=req_ipv4.proto))
        ack_pkt.add_protocol(udp.udp(src_port=67, dst_port=68))
        ack_pkt.add_protocol(
            dhcp.dhcp(op=2,
                      chaddr=req_eth.src,
                      siaddr=self.dhcp_server,
                      boot_file=req.boot_file,
                      yiaddr=(self.networkMap.findActiveHostByMac(
                          req_eth.src).ip),
                      xid=req.xid,
                      options=req.options))
        ack_pkt.serialize()
        return ack_pkt
예제 #26
0
파일: dhcp.py 프로젝트: John-Lin/nat
    def handle_dhcp_request(self, dhcp_pkt, datapath, port):
        # send dhcp_ack message.
        dhcp_ack_msg_type = '\x05'
        self.logger.info("Send DHCP message type %s" %
                         (self.dhcp_msg_type_code[ord(dhcp_ack_msg_type)]))

        subnet_option = dhcp.option(tag=dhcp.DHCP_SUBNET_MASK_OPT,
                                    value=addrconv.ipv4.text_to_bin(self.ip_network.netmask))
        gw_option = dhcp.option(tag=dhcp.DHCP_GATEWAY_ADDR_OPT,
                                value=addrconv.ipv4.text_to_bin(self.gw_addr))
        dns_option = dhcp.option(tag=dhcp.DHCP_DNS_SERVER_ADDR_OPT,
                                 value=addrconv.ipv4.text_to_bin(self.dns_addr))
        time_option = dhcp.option(tag=dhcp.DHCP_IP_ADDR_LEASE_TIME_OPT,
                                  value='\xFF\xFF\xFF\xFF')
        msg_option = dhcp.option(tag=dhcp.DHCP_MESSAGE_TYPE_OPT,
                                 value=dhcp_ack_msg_type)
        id_option = dhcp.option(tag=dhcp.DHCP_SERVER_IDENTIFIER_OPT,
                                value=addrconv.ipv4.text_to_bin(self.dhcp_addr))

        options = dhcp.options(option_list=[msg_option, id_option,
                               time_option, subnet_option,
                               gw_option, dns_option])
        hlen = len(addrconv.mac.text_to_bin(dhcp_pkt.chaddr))

        # Look up IP by using client mac address
        client_ip_addr = self.mac_to_client_ip[dhcp_pkt.chaddr]

        dhcp_pkt = dhcp.dhcp(op=dhcp.DHCP_BOOT_REPLY,
                             hlen=hlen,
                             chaddr=dhcp_pkt.chaddr,
                             yiaddr=client_ip_addr,
                             giaddr=dhcp_pkt.giaddr,
                             xid=dhcp_pkt.xid,
                             options=options)

        self._send_dhcp_packet(datapath, dhcp_pkt, port)
예제 #27
0
    def _handle_dhcp(self, pkt_dhcp, datapath, in_port):
        dhcp_type = ord(pkt_dhcp.options.option_list[0].value)
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        # the message is DHCP_ DISCOVERY
        if dhcp_type == 1:
            self.logger.info("Recieve DHCP_DISCOVERY")
            dhcp_offer = '\x02'
            self.logger.info("Send DHCP_OFFER")
            msg_option = dhcp.option(tag=53, value=dhcp_offer)
            options = dhcp.options(option_list=[msg_option])
            # allocate ip to host
            yiaddr = self.ip_pool[0]
            # generate the DHCP_OFFER packet
            pkt_dhcp = dhcp.dhcp(op=2,
                                 chaddr=pkt_dhcp.chaddr,
                                 options=options,
                                 hlen=6,
                                 htype=1,
                                 xid=pkt_dhcp.xid,
                                 ciaddr=pkt_dhcp.ciaddr,
                                 yiaddr=yiaddr)
            pkt = packet.Packet()
            pkt.add_protocol(
                ethernet.ethernet(src=self.hw_addr, dst="ff:ff:ff:ff:ff:ff"))
            pkt.add_protocol(
                ipv4.ipv4(src=self.ip, dst="255.255.255.255", proto=17))
            pkt.add_protocol(udp.udp(src_port=67, dst_port=68))
            pkt.add_protocol(pkt_dhcp)
            self._send_packet(datapath, in_port, pkt)

        # the message is DHCP_REQUEST
        if dhcp_type == 3:
            self.logger.info("Recieve DHCP_REQUEST")
            dhcp_ack = '\x05'
            self.logger.info("Send DHCP_ACK")
            # set packet type
            msg_option = dhcp.option(tag=53, value=dhcp_ack)
            # set dhcp valid time
            time_option = dhcp.option(tag=51, value='\x00\xFF\xFF\xFF')
            # set net mask
            mask_option = dhcp.option(tag=1, value=self.netmask)
            options = dhcp.options(
                option_list=[msg_option, time_option, mask_option])
            yiaddr = self.ip_pool[0]
            # delete the used ip
            self.ip_pool.pop(0)
            # generate the DHCP_ACK
            pkt_dhcp = dhcp.dhcp(op=5,
                                 chaddr=pkt_dhcp.chaddr,
                                 options=options,
                                 hlen=6,
                                 htype=1,
                                 xid=pkt_dhcp.xid,
                                 ciaddr=pkt_dhcp.ciaddr,
                                 yiaddr=yiaddr)
            pkt = packet.Packet()
            pkt.add_protocol(
                ethernet.ethernet(src=self.hw_addr, dst="ff:ff:ff:ff:ff:ff"))
            pkt.add_protocol(
                ipv4.ipv4(src=self.ip, dst="255.255.255.255", proto=17))
            pkt.add_protocol(udp.udp(src_port=67, dst_port=68))
            pkt.add_protocol(pkt_dhcp)
            self._send_packet(datapath, in_port, pkt)

            # install flow table 0
            cookie = 0
            cookie_mask = 0
            table_id = 0
            next_table_id = 3
            priority = 2000
            buffer_id = ofproto.OFP_NO_BUFFER
            print(pkt_dhcp.chaddr)
            match = parser.OFPMatch(eth_type=0x800,
                                    eth_src=pkt_dhcp.chaddr,
                                    ip_proto=17,
                                    udp_src=68)
            instruction = [parser.OFPInstructionGotoTable(next_table_id)]
            req = parser.OFPFlowMod(datapath=datapath,
                                    command=ofproto.OFPFC_ADD,
                                    cookie=cookie,
                                    cookie_mask=cookie_mask,
                                    table_id=table_id,
                                    priority=priority,
                                    match=match,
                                    instructions=instruction)
            datapath.send_msg(req)

            # insatll flow table 3
            table_id = 3
            priority = 3000
            instruction = [
                parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, [])
            ]
            req = parser.OFPFlowMod(datapath=datapath,
                                    command=ofproto.OFPFC_ADD,
                                    cookie=cookie,
                                    cookie_mask=cookie_mask,
                                    table_id=table_id,
                                    priority=priority,
                                    out_port=ofproto.OFPP_ANY,
                                    match=match,
                                    instructions=instruction)
            datapath.send_msg(req)
예제 #28
0
    def _create_dhcp_packet(self, packet, dhcp_packet, pkt_type, lport):
        pkt_ipv4 = packet.get_protocol(ipv4.ipv4)
        pkt_ethernet = packet.get_protocol(ethernet.ethernet)

        try:
            subnet = lport.subnets[0]
        except IndexError:
            LOG.warning("No subnet found for port %s", lport.id)
            return

        pkt_type_packed = struct.pack('!B', pkt_type)
        dns = self._get_dns_address_list_bin(subnet)
        host_routes = self._get_host_routes_list_bin(subnet, lport)
        dhcp_server_address = subnet.dhcp_ip
        if not dhcp_server_address:
            LOG.warning("Could not find DHCP server address for subnet %s",
                        subnet.id)
            return
        netmask_bin = subnet.cidr.netmask.packed
        domain_name_bin = struct.pack('!%ss' % len(self.domain_name),
                                      self.domain_name)
        lease_time_bin = struct.pack('!I', self.lease_time)
        option_list = [
            dhcp.option(dhcp.DHCP_MESSAGE_TYPE_OPT, pkt_type_packed),
            dhcp.option(dhcp.DHCP_SUBNET_MASK_OPT, netmask_bin),
            dhcp.option(dhcp.DHCP_IP_ADDR_LEASE_TIME_OPT, lease_time_bin),
            dhcp.option(dhcp.DHCP_SERVER_IDENTIFIER_OPT,
                        dhcp_server_address.packed),
            dhcp.option(dhcp.DHCP_DNS_SERVER_ADDR_OPT, dns),
            dhcp.option(dhcp.DHCP_DOMAIN_NAME_OPT, domain_name_bin),
            dhcp.option(dhcp.DHCP_CLASSLESS_ROUTE_OPT, host_routes),
        ]
        gw_ip = self._get_port_gateway_address(subnet, lport)
        if gw_ip:
            option_list.append(
                dhcp.option(dhcp.DHCP_GATEWAY_ADDR_OPT,
                            netaddr.IPAddress(gw_ip).packed))

        if pkt_type == dhcp.DHCP_ACK:
            intreface_mtu = self._get_port_mtu(lport)
            mtu_bin = struct.pack('!H', intreface_mtu)
            option_list.append(
                dhcp.option(dhcp.DHCP_INTERFACE_MTU_OPT, mtu_bin))
        options = dhcp.options(option_list=option_list)
        dhcp_pkt = ryu_packet.Packet()
        dhcp_pkt.add_protocol(
            ethernet.ethernet(ethertype=ether.ETH_TYPE_IP,
                              dst=pkt_ethernet.src,
                              src=pkt_ethernet.dst))
        dhcp_pkt.add_protocol(
            ipv4.ipv4(dst=pkt_ipv4.src,
                      src=dhcp_server_address,
                      proto=pkt_ipv4.proto))
        dhcp_pkt.add_protocol(
            udp.udp(src_port=const.DHCP_SERVER_PORT,
                    dst_port=const.DHCP_CLIENT_PORT))
        dhcp_pkt.add_protocol(
            dhcp.dhcp(op=dhcp.DHCP_BOOT_REPLY,
                      chaddr=pkt_ethernet.src,
                      siaddr=dhcp_server_address,
                      boot_file=dhcp_packet.boot_file,
                      yiaddr=lport.ip,
                      xid=dhcp_packet.xid,
                      options=options))
        return dhcp_pkt
예제 #29
0
파일: dhcpd.py 프로젝트: chenleji/ryu
    def _respond_dhcp(self, datapath, port, pool,
                      pkt_ethernet, pkt_vlan, pkt_ip, pkt_udp, pkt_dhcp):
        # DHCP message type code
        options = dict()
        for option in pkt_dhcp.options.option_list:
            options[option.tag] = option.value
        src = pkt_dhcp.chaddr

        # RESPONSE MSG
        pkt = packet.Packet()
        pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype,
                                           dst=pkt_ethernet.src,
                                           src='00:00:00:00:00:00'))
        if pkt_vlan:
            pkt.add_protocol(vlan.vlan(cfi=pkt_vlan.cfi,
                                       ethertype=pkt_vlan.ethertype,
                                       pcp=pkt_vlan.pcp,
                                       vid=pkt_vlan.vid))
        pkt.add_protocol(ipv4.ipv4(src=pkt_ip.dst, dst=pkt_ip.src, proto=in_proto.IPPROTO_UDP))
        pkt.add_protocol(udp.udp(src_port=pkt_udp.dst_port, dst_port=pkt_udp.src_port))

        # DISCOVER MSG
        dhcp_msg_type = ord(options[dhcp.DHCP_MESSAGE_TYPE_OPT])
        if dhcp_msg_type == dhcp.DHCP_DISCOVER:
            msg_type = dhcp.DHCP_OFFER
            if src in self.leases:
                offer = self.leases[src]
                del self.leases[src]
                self.offers[src] = offer
            else:
                offer = self.offers.get(src)
                if offer is None:
                    if len(pool) == 0:
                        LOG.error("Out of IP addresses")
                        msg_type = dhcp.DHCP_NAK

                    offer = pool[0]
                    if dhcp.DHCP_REQUESTED_IP_ADDR_OPT in options:
                        wanted_ip = IPAddr(addrconv.ipv4.bin_to_text(options[dhcp.DHCP_REQUESTED_IP_ADDR_OPT].value))
                        if wanted_ip in pool:
                            offer = wanted_ip
                    pool.remove(offer)
                    self.offers[src] = offer
            wanted_opts = list()
            if dhcp.DHCP_PARAMETER_REQUEST_LIST_OPT in options:
                fmt = "s" * len(options[dhcp.DHCP_PARAMETER_REQUEST_LIST_OPT])
                wanted_opt_set = struct.unpack(fmt, options[dhcp.DHCP_PARAMETER_REQUEST_LIST_OPT])
                for i in wanted_opt_set:
                    wanted_opts.append(ord(i))
            option_list = list()
            option_list.append(dhcp.option(dhcp.DHCP_MESSAGE_TYPE_OPT, chr(msg_type), length=1))
            if msg_type is not dhcp.DHCP_NAK:
                if dhcp.DHCP_SUBNET_MASK_OPT in wanted_opts:
                    option_list.append(dhcp.option(dhcp.DHCP_SUBNET_MASK_OPT,
                                                   addrconv.ipv4.text_to_bin(self.subnet.toStr()),
                                                   length=4))
                if dhcp.DHCP_GATEWAY_ADDR_OPT in wanted_opts and self.router_addr is not None:
                    option_list.append(dhcp.option(dhcp.DHCP_GATEWAY_ADDR_OPT,
                                                   addrconv.ipv4.text_to_bin(self.router_addr.toStr()),
                                                   length=4))
                if dhcp.DHCP_DNS_SERVER_ADDR_OPT in wanted_opts and self.dns_addr is not None:
                    option_list.append(dhcp.option(dhcp.DHCP_DNS_SERVER_ADDR_OPT,
                                                   addrconv.ipv4.text_to_bin(self.dns_addr.toStr()),
                                                   length=4))
                option_list.append(dhcp.option(dhcp.DHCP_IP_ADDR_LEASE_TIME_OPT,
                                               chr(self.lease_time),
                                               length=4))
                option_list.append(dhcp.option(dhcp.DHCP_RENEWAL_TIME_OPT, chr(self.lease_time / 2), length=4))
                option_list.append(dhcp.option(dhcp.DHCP_REBINDING_TIME_OPT, chr(self.lease_time * 7 / 8), length=4))
            resp_options = dhcp.options(option_list=option_list)
            pkt.add_protocol(dhcp.dhcp(op=self._MSG_TYPE_BOOT_REPLY, chaddr=pkt_dhcp.chaddr, options=resp_options,
                                       xid=pkt_dhcp.xid, ciaddr=pkt_dhcp.ciaddr, yiaddr=offer.toStr(),
                                       siaddr=self.ip_addr.toStr(), giaddr='0.0.0.0', sname='', boot_file=''))

        # REQUEST MSG
        if dhcp_msg_type == dhcp.DHCP_REQUEST:
            msg_type = dhcp.DHCP_ACK
            if dhcp.DHCP_REQUESTED_IP_ADDR_OPT not in options:
                return
            wanted_ip = IPAddr(addrconv.ipv4.bin_to_text(options[dhcp.DHCP_REQUESTED_IP_ADDR_OPT]))
            got_ip = None
            if src in self.leases:
                if wanted_ip != self.leases[src]:
                    pool.append(self.leases[src])
                    del self.leases[src]
                else:
                    got_ip = self.leases[src]
            if got_ip is None:
                if src in self.offers:
                    if wanted_ip != self.offers[src]:
                        pool.append(self.offers[src])
                        del self.offers[src]
                    else:
                        got_ip = self.offers[src]
            if got_ip is None:
                if wanted_ip in pool:
                    pool.remove(wanted_ip)
                    got_ip = wanted_ip
            if got_ip is None:
                LOG.warn("%s asked for un-offered %s", src, wanted_ip.toStr())
                msg_type = dhcp.DHCP_NAK
            wanted_opts = list()
            if dhcp.DHCP_PARAMETER_REQUEST_LIST_OPT in options:
                fmt = "s" * len(options[dhcp.DHCP_PARAMETER_REQUEST_LIST_OPT])
                wanted_opt_set = struct.unpack(fmt, options[dhcp.DHCP_PARAMETER_REQUEST_LIST_OPT])
                for i in wanted_opt_set:
                    wanted_opts.append(ord(i))
            # DHCP options tag code
            option_list = list()
            option_list.append(dhcp.option(dhcp.DHCP_MESSAGE_TYPE_OPT, chr(msg_type), length=1))
            if msg_type is not dhcp.DHCP_NAK:
                if dhcp.DHCP_SUBNET_MASK_OPT in wanted_opts:
                    option_list.append(dhcp.option(dhcp.DHCP_SUBNET_MASK_OPT,
                                                   addrconv.ipv4.text_to_bin(self.subnet.toStr()),
                                                   length=4))
                if dhcp.DHCP_GATEWAY_ADDR_OPT in wanted_opts and self.router_addr is not None:
                    option_list.append(dhcp.option(dhcp.DHCP_GATEWAY_ADDR_OPT,
                                                   addrconv.ipv4.text_to_bin(self.router_addr.toStr()),
                                                   length=4))
                if dhcp.DHCP_DNS_SERVER_ADDR_OPT in wanted_opts and self.dns_addr is not None:
                    option_list.append(dhcp.option(dhcp.DHCP_DNS_SERVER_ADDR_OPT,
                                                   addrconv.ipv4.text_to_bin(self.dns_addr.toStr()),
                                                   length=4))
                option_list.append(dhcp.option(dhcp.DHCP_IP_ADDR_LEASE_TIME_OPT,
                                               chr(self.lease_time),
                                               length=4))
                option_list.append(dhcp.option(dhcp.DHCP_RENEWAL_TIME_OPT, chr(self.lease_time / 2), length=4))
                option_list.append(dhcp.option(dhcp.DHCP_REBINDING_TIME_OPT, chr(self.lease_time * 7 / 8), length=4))
            resp_options = dhcp.options(option_list=option_list)
            pkt.add_protocol(dhcp.dhcp(op=self._MSG_TYPE_BOOT_REPLY, chaddr=pkt_dhcp.chaddr, options=resp_options,
                                       xid=pkt_dhcp.xid, ciaddr=pkt_dhcp.ciaddr, yiaddr=wanted_ip.toStr(),
                                       siaddr=self.ip_addr.toStr(), giaddr='0.0.0.0', sname='', boot_file=''))

        # RELEASE MSG
        if dhcp_msg_type == dhcp.DHCP_RELEASE:
            if self.leases.get(src).toStr() != pkt_dhcp.ciaddr:
                LOG.warn("%s tried to release unleased %s" % (src, pkt_dhcp.ciaddr))
                return
            del self.leases[src]
            pool.append(pkt_dhcp.ciaddr)
            LOG.info("%s released %s" % (src, pkt_dhcp.ciaddr))

        self._send_dhcp_reply(datapath, port, pkt)
        return True
예제 #30
0
파일: dhcps.py 프로젝트: xixi2/ryu_sdn
 def assemble_offer(self, port, pkt):
     #self.semaphore.acquire()
     disc_eth = pkt.get_protocol(ethernet.ethernet)
     disc_ipv4 = pkt.get_protocol(ipv4.ipv4)
     disc_udp = pkt.get_protocol(udp.udp)
     disc = pkt.get_protocol(dhcp.dhcp)
     try:
         disc.options.option_list.remove(
             next(opt for opt in disc.options.option_list if opt.tag == 50))
     except:
         pass
     disc.options.option_list.remove(
         next(opt for opt in disc.options.option_list if opt.tag == 55))
     disc.options.option_list.remove(
         next(opt for opt in disc.options.option_list if opt.tag == 53))
     disc.options.option_list.remove(
         next(opt for opt in disc.options.option_list if opt.tag == 12))
     disc.options.option_list.insert(
         0, dhcp.option(tag=1, value=self.bin_netmask))
     disc.options.option_list.insert(
         0, dhcp.option(tag=3, value=self.bin_server))
     disc.options.option_list.insert(0,
                                     dhcp.option(tag=6, value=self.bin_dns))
     # disc.options.option_list.insert(
     #     0, dhcp.option(tag=12, value=self.hostname))
     disc.options.option_list.insert(
         0, dhcp.option(tag=51, value=struct.pack('!I', self.release_time)))
     disc.options.option_list.insert(
         0, dhcp.option(tag=53, value=struct.pack('!B', 2)))
     # disc.options.option_list.insert(
     #     0, dhcp.option(tag=54, value=self.hostname))
     disc.options.option_list.insert(
         0,
         dhcp.option(tag=58,
                     value=struct.pack('!I', self.release_time // 2)))
     disc.options.option_list.insert(
         0,
         dhcp.option(tag=59,
                     value=struct.pack('!I', self.release_time * 7 // 8)))
     if disc_eth.src not in self.ip_pool:
         nid = random.choice(self.usable_id)
         nip = self.ip_addr + str(nid)
         #print("new host in,mac:" + disc_eth.src + ",ip:" + nip)
         self.usable_id.remove(nid)
         self.ip_pool[disc_eth.src] = [nip, time.perf_counter()]
     else:
         self.ip_pool[disc_eth.src][1] = time.perf_counter()
     #print(disc_eth.src, str(self.mac_port[disc_eth.src][1])+":"+str(self.mac_port[disc_eth.src][1]))
     h = switches.Host(
         disc_eth.src,
         str(self.mac_port[disc_eth.src][0]) + ":" +
         str(self.mac_port[disc_eth.src][1]))
     h.ipv4.append(self.ip_pool[disc_eth.src][0])
     self.send_event_to_observers(event.EventHostAdd(h))
     nip = self.ip_pool[disc_eth.src][0]
     offer_pkt = packet.Packet()
     offer_pkt.add_protocol(
         ethernet.ethernet(ethertype=disc_eth.ethertype,
                           dst=disc_eth.src,
                           src=self.hw_addr))
     offer_pkt.add_protocol(
         ipv4.ipv4(dst=disc_ipv4.dst,
                   src=self.dhcp_server,
                   proto=disc_ipv4.proto))
     offer_pkt.add_protocol(udp.udp(src_port=67, dst_port=68))
     offer_pkt.add_protocol(
         dhcp.dhcp(op=2,
                   chaddr=disc_eth.src,
                   siaddr=self.dhcp_server,
                   boot_file=disc.boot_file,
                   yiaddr=nip,
                   xid=disc.xid,
                   options=disc.options))
     return offer_pkt
예제 #31
0
class Test_dhcp_offer_with_hlen_zero(unittest.TestCase):

    op = dhcp.DHCP_BOOT_REPLY
    chaddr = 'aa:aa:aa:aa:aa:aa'
    htype = 1
    hlen = 6
    hops = 0
    xid = 1
    secs = 0
    flags = 1
    ciaddr = '192.168.10.10'
    yiaddr = '192.168.20.20'
    siaddr = '192.168.30.30'
    giaddr = '192.168.40.40'
    sname = 'abc'
    boot_file = ''

    option_list = [
        dhcp.option(dhcp.DHCP_MESSAGE_TYPE_OPT, b'\x02', 1),
        dhcp.option(dhcp.DHCP_SUBNET_MASK_OPT, b'\xff\xff\xff\x00', 4),
        dhcp.option(dhcp.DHCP_GATEWAY_ADDR_OPT, b'\xc0\xa8\x0a\x09', 4),
        dhcp.option(dhcp.DHCP_DNS_SERVER_ADDR_OPT, b'\xc0\xa8\x0a\x09', 4),
        dhcp.option(dhcp.DHCP_IP_ADDR_LEASE_TIME_OPT, b'\x00\x03\xf4\x80', 4),
        dhcp.option(dhcp.DHCP_RENEWAL_TIME_OPT, b'\x00\x01\xfa\x40', 4),
        dhcp.option(dhcp.DHCP_REBINDING_TIME_OPT, b'\x00\x03\x75\xf0', 4),
        dhcp.option(dhcp.DHCP_SERVER_IDENTIFIER_OPT, b'\xc0\xa8\x0a\x09', 4)
    ]
    magic_cookie = '99.130.83.99'
    options = dhcp.options(option_list=option_list,
                           options_len=50,
                           magic_cookie=magic_cookie)

    dh = dhcp.dhcp(op,
                   chaddr,
                   options,
                   htype=htype,
                   hlen=0,
                   hops=hops,
                   xid=xid,
                   secs=secs,
                   flags=flags,
                   ciaddr=ciaddr,
                   yiaddr=yiaddr,
                   siaddr=siaddr,
                   giaddr=giaddr,
                   sname=sname,
                   boot_file=boot_file)

    def test_init(self):
        eq_(self.op, self.dh.op)
        eq_(self.htype, self.dh.htype)
        eq_(self.hlen, self.dh.hlen)
        eq_(self.hops, self.dh.hops)
        eq_(self.xid, self.dh.xid)
        eq_(self.secs, self.dh.secs)
        eq_(self.flags, self.dh.flags)
        eq_(self.ciaddr, self.dh.ciaddr)
        eq_(self.yiaddr, self.dh.yiaddr)
        eq_(self.siaddr, self.dh.siaddr)
        eq_(self.giaddr, self.dh.giaddr)
        eq_(self.chaddr, self.dh.chaddr)
        eq_(self.sname, self.dh.sname)
        eq_(self.boot_file, self.dh.boot_file)
        eq_(str(self.options), str(self.dh.options))
예제 #32
0
class Test_dhcp_offer(unittest.TestCase):

    op = dhcp.DHCP_BOOT_REPLY
    chaddr = 'aa:aa:aa:aa:aa:aa'
    htype = 1
    hlen = 6
    hops = 0
    xid = 1
    secs = 0
    flags = 1
    ciaddr = '192.168.10.10'
    yiaddr = '192.168.20.20'
    siaddr = '192.168.30.30'
    giaddr = '192.168.40.40'
    sname = 'abc'
    boot_file = b''

    option_list = [
        dhcp.option(dhcp.DHCP_MESSAGE_TYPE_OPT, b'\x02', 1),
        dhcp.option(dhcp.DHCP_SUBNET_MASK_OPT, b'\xff\xff\xff\x00', 4),
        dhcp.option(dhcp.DHCP_GATEWAY_ADDR_OPT, b'\xc0\xa8\x0a\x09', 4),
        dhcp.option(dhcp.DHCP_DNS_SERVER_ADDR_OPT, b'\xc0\xa8\x0a\x09', 4),
        dhcp.option(dhcp.DHCP_IP_ADDR_LEASE_TIME_OPT, b'\x00\x03\xf4\x80', 4),
        dhcp.option(dhcp.DHCP_RENEWAL_TIME_OPT, b'\x00\x01\xfa\x40', 4),
        dhcp.option(dhcp.DHCP_REBINDING_TIME_OPT, b'\x00\x03\x75\xf0', 4),
        dhcp.option(dhcp.DHCP_SERVER_IDENTIFIER_OPT, b'\xc0\xa8\x0a\x09', 4)
    ]
    magic_cookie = '99.130.83.99'
    options = dhcp.options(option_list=option_list,
                           options_len=50,
                           magic_cookie=magic_cookie)

    dh = dhcp.dhcp(op,
                   chaddr,
                   options,
                   htype=htype,
                   hlen=hlen,
                   hops=hops,
                   xid=xid,
                   secs=secs,
                   flags=flags,
                   ciaddr=ciaddr,
                   yiaddr=yiaddr,
                   siaddr=siaddr,
                   giaddr=giaddr,
                   sname=sname,
                   boot_file=boot_file)

    buf = b"\x02\x01\x06\x00\x00\x00\x00\x01\x00\x00\x00\x01\xc0\xa8\x0a\x0a"\
        + b"\xc0\xa8\x14\x14\xc0\xa8\x1e\x1e\xc0\xa8\x28\x28\xaa\xaa\xaa\xaa"\
        + b"\xaa\xaa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x61\x62\x63\x00"\
        + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
        + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
        + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
        + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
        + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
        + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
        + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
        + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
        + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
        + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
        + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
        + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x63\x82\x53\x63"\
        + b"\x35\x01\x02\x01\x04\xff\xff\xff\x00\x03\x04\xc0\xa8\x0a\x09\x06"\
        + b"\x04\xc0\xa8\x0a\x09\x33\x04\x00\x03\xf4\x80\x3a\x04\x00\x01\xfa"\
        + b"\x40\x3b\x04\x00\x03\x75\xf0\x36\x04\xc0\xa8\x0a\x09\xff"

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_init(self):
        eq_(self.op, self.dh.op)
        eq_(self.htype, self.dh.htype)
        eq_(self.hlen, self.dh.hlen)
        eq_(self.hops, self.dh.hops)
        eq_(self.xid, self.dh.xid)
        eq_(self.secs, self.dh.secs)
        eq_(self.flags, self.dh.flags)
        eq_(self.ciaddr, self.dh.ciaddr)
        eq_(self.yiaddr, self.dh.yiaddr)
        eq_(self.siaddr, self.dh.siaddr)
        eq_(self.giaddr, self.dh.giaddr)
        eq_(self.chaddr, self.dh.chaddr)
        eq_(self.sname, self.dh.sname)
        eq_(self.boot_file, self.dh.boot_file)
        eq_(str(self.options), str(self.dh.options))

    def test_parser(self):
        _res = self.dh.parser(self.buf)
        if type(_res) is tuple:
            res = _res[0]
        else:
            res = _res

        eq_(self.op, res.op)
        eq_(self.htype, res.htype)
        eq_(self.hlen, res.hlen)
        eq_(self.hops, res.hops)
        eq_(self.xid, res.xid)
        eq_(self.secs, res.secs)
        eq_(self.flags, res.flags)
        eq_(self.ciaddr, res.ciaddr)
        eq_(self.yiaddr, res.yiaddr)
        eq_(self.siaddr, res.siaddr)
        eq_(self.giaddr, res.giaddr)
        eq_(self.chaddr, res.chaddr)
        # sname is 64 byte length. rest of data is filled by '\x00'.
        eq_(self.sname.ljust(64, '\x00'), res.sname)
        # boof_file is 128 byte length. rest of data is filled by '\x00'.
        eq_(self.boot_file.ljust(128, b'\x00'), res.boot_file)
        eq_(str(self.options), str(res.options))

    def test_parser_corrupted(self):
        buf = self.buf[:128 - (14 + 20 + 8)]
        _res = self.dh.parser(buf)

    def test_serialize(self):
        data = bytearray()
        prev = None
        buf = self.dh.serialize(data, prev)

        res = struct.unpack_from(dhcp.dhcp._DHCP_PACK_STR,
                                 six.binary_type(buf))

        eq_(self.op, res[0])
        eq_(self.htype, res[1])
        eq_(self.hlen, res[2])
        eq_(self.hops, res[3])
        eq_(self.xid, res[4])
        eq_(self.secs, res[5])
        eq_(self.flags, res[6])
        eq_(self.ciaddr, addrconv.ipv4.bin_to_text(res[7]))
        eq_(self.yiaddr, addrconv.ipv4.bin_to_text(res[8]))
        eq_(self.siaddr, addrconv.ipv4.bin_to_text(res[9]))
        eq_(self.giaddr, addrconv.ipv4.bin_to_text(res[10]))
        eq_(self.chaddr, addrconv.mac.bin_to_text(res[11][:6]))
        # sname is 64 byte length. rest of data is filled by '\x00'.
        eq_(self.sname.ljust(64, '\x00'), res[12].decode('ascii'))
        # boof_file is 128 byte length. rest of data is filled by '\x00'.
        eq_(self.boot_file.ljust(128, b'\x00'), res[13])
        options = dhcp.options.parser(
            buf[struct.calcsize(dhcp.dhcp._DHCP_PACK_STR):])
        eq_(str(self.options), str(options))

    def test_to_string(self):
        option_values = ['tag', 'length', 'value']
        opt_str_list = []
        for option in self.option_list:
            _opt_str = ','.join([
                '%s=%s' % (k, repr(getattr(option, k)))
                for k, v in inspect.getmembers(option) if k in option_values
            ])
            opt_str = '%s(%s)' % (dhcp.option.__name__, _opt_str)
            opt_str_list.append(opt_str)
        option_str = '[%s]' % ', '.join(opt_str_list)

        opts_vals = {
            'magic_cookie': repr(self.magic_cookie),
            'option_list': option_str,
            'options_len': repr(self.options.options_len)
        }
        _options_str = ','.join([
            '%s=%s' % (k, opts_vals[k])
            for k, v in inspect.getmembers(self.options) if k in opts_vals
        ])
        options_str = '%s(%s)' % (dhcp.options.__name__, _options_str)

        dhcp_values = {
            'op': repr(self.op),
            'htype': repr(self.htype),
            'hlen': repr(self.hlen),
            'hops': repr(self.hops),
            'xid': repr(self.xid),
            'secs': repr(self.secs),
            'flags': repr(self.flags),
            'ciaddr': repr(self.ciaddr),
            'yiaddr': repr(self.yiaddr),
            'siaddr': repr(self.siaddr),
            'giaddr': repr(self.giaddr),
            'chaddr': repr(self.chaddr),
            'sname': repr(self.sname),
            'boot_file': repr(self.boot_file),
            'options': options_str
        }
        _dh_str = ','.join([
            '%s=%s' % (k, dhcp_values[k])
            for k, v in inspect.getmembers(self.dh) if k in dhcp_values
        ])
        dh_str = '%s(%s)' % (dhcp.dhcp.__name__, _dh_str)

        eq_(str(self.dh), dh_str)
        eq_(repr(self.dh), dh_str)

    def test_json(self):
        jsondict = self.dh.to_jsondict()
        dh = dhcp.dhcp.from_jsondict(jsondict['dhcp'])
        eq_(str(self.dh), str(dh))