Check if the current settings conform to the LISP specifications and
        fix where possible.

def sanitize(self):
        '''
        Check if the current settings conform to the LISP specifications and
        fix where possible.
        '''
        # Record TTL:  The time in minutes the recipient of the Map-Reply will
        # store the mapping.  If the TTL is 0, the entry SHOULD be removed
        # from the cache immediately.  If the value is 0xffffffff, the
        # recipient can decide locally how long to store the mapping.
        if not isinstance(self.ttl, numbers.Integral) \
        or self.ttl < 0 or self.ttl > 0xffffffff:
            raise ValueError('Invalid TTL')

        # ACT:  This 3-bit field describes negative Map-Reply actions.  In any
        # other message type, these bits are set to 0 and ignored on
        # receipt.  These bits are used only when the 'Locator Count' field
        # is set to 0.  The action bits are encoded only in Map-Reply
        # messages.  The actions defined are used by an ITR or PITR when a
        # destination EID matches a negative mapping cache entry.
        # Unassigned values should cause a map-cache entry to be created
        # and, when packets match this negative cache entry, they will be
        # dropped.  The current assigned values are:
        #
        #  (0) No-Action:  The map-cache is kept alive and no packet
        #     encapsulation occurs.
        #
        #  (1) Natively-Forward:  The packet is not encapsulated or dropped
        #     but natively forwarded.
        #
        #  (2) Send-Map-Request:  The packet invokes sending a Map-Request.
        #
        #  (3) Drop:  A packet that matches this map-cache entry is dropped.
        #     An ICMP Unreachable message SHOULD be sent.
        if self.locator_records:
            self.action = self.ACT_NO_ACTION

        if self.action not in (self.ACT_NO_ACTION,
                               self.ACT_NATIVELY_FORWARD,
                               self.ACT_SEND_MAP_REQUEST,
                               self.ACT_DROP):
            raise ValueError('Invalid Negative Map-Reply action')

        # A: The Authoritative bit, when sent is always set to 1 by an ETR.
        # When a Map-Server is proxy Map-Replying [LISP-MS] for a LISP site,
        # the Authoritative bit is set to 0.  This indicates to requesting
        # ITRs that the Map-Reply was not originated by a LISP node managed
        # at the site that owns the EID-prefix.
        if not isinstance(self.authoritative, bool):
            raise ValueError('Authoritative flag must be a boolean')

        # Map-Version Number:  When this 12-bit value is non-zero the Map-Reply
        # sender is informing the ITR what the version number is for the
        # EID-record contained in the Map-Reply.  The ETR can allocate this
        # number internally but MUST coordinate this value with other ETRs
        # for the site.  When this value is 0, there is no versioning
        # information conveyed.  The Map-Version Number can be included in
        # Map-Request and Map-Register messages.  See Section 6.6.3 for more
        # details.
        if not isinstance(self.map_version, numbers.Integral) \
        or self.map_version < 0 \
        or self.map_version >= 2 ** 12:
            raise ValueError('Invalid map version')

        # EID-prefix:  4 octets if an IPv4 address-family, 16 octets if an IPv6
        # address-family.
        if not isinstance(self.eid_prefix, (IPv4Network, IPv6Network)):
            raise ValueError('EID prefix must be IPv4 or IPv6')

        # Check locator records
        for locator_record in self.locator_records:
            if not isinstance(locator_record, LocatorRecord):
                raise ValueError('Invalid Locator record')

            locator_record.sanitize()

        # For each Map-Reply record, the list of Locators in a Locator-Set MUST
        # appear in the same order for each ETR that originates a Map-Reply
        # message.  The Locator-Set MUST be sorted in order of ascending IP
        # address where an IPv4 locator address is considered numerically 'less
        # than' an IPv6 locator address.
        self.locator_records.sort(key=LocatorRecord.sort_key)