Example #1
0
    def init_response(bundle: TransactionBundle):
        """
        Create the message object in bundle.response

        :param bundle: The transaction bundle
        """
        # Start building the response
        if isinstance(bundle.request, SolicitMessage):
            bundle.response = AdvertiseMessage(bundle.request.transaction_id)

        elif isinstance(bundle.request, (RequestMessage, RenewMessage, RebindMessage,
                                         ReleaseMessage, DeclineMessage, InformationRequestMessage)):
            bundle.response = ReplyMessage(bundle.request.transaction_id)

        elif isinstance(bundle.request, ConfirmMessage):
            # Receipt of Confirm Messages: If [...] there were no addresses in any of the IAs sent by the client, the
            # server MUST NOT send a reply to the client.
            for option in bundle.request.get_options_of_type((IANAOption, IATAOption, IAPDOption)):
                if option.get_options_of_type((IAAddressOption, IAPrefixOption)):
                    # Found an address or prefix option
                    break
            else:
                # Not found: ignore request
                raise CannotRespondError("No IAs present in confirm reply")

            bundle.response = ReplyMessage(bundle.request.transaction_id)

        else:
            raise CannotRespondError("Do not know how to reply to {}".format(type(bundle.request).__name__))

        # Build the plain chain of relay reply messages
        bundle.create_outgoing_relay_messages()
Example #2
0
advertise_message = AdvertiseMessage(
    transaction_id=bytes.fromhex('f350d6'),
    options=[
        IANAOption(iaid=bytes.fromhex('c43cb2f1'),
                   options=[
                       IAAddressOption(
                           address=IPv6Address('2001:db8:ffff:1:c::e09c'),
                           preferred_lifetime=375,
                           valid_lifetime=600),
                   ]),
        IAPDOption(iaid=bytes.fromhex('c43cb2f1'),
                   options=[
                       IAPrefixOption(
                           prefix=IPv6Network('2001:db8:ffcc:fe00::/56'),
                           preferred_lifetime=375,
                           valid_lifetime=600),
                   ]),
        ClientIdOption(duid=LinkLayerDUID(hardware_type=1,
                                          link_layer_address=bytes.fromhex(
                                              '3431c43cb2f1'))),
        ServerIdOption(duid=LinkLayerTimeDUID(hardware_type=1,
                                              time=488458703,
                                              link_layer_address=bytes.fromhex(
                                                  '00137265ca42'))),
        ReconfigureAcceptOption(),
        RecursiveNameServersOption(
            dns_servers=[IPv6Address('2001:4860:4860::8888')]),
    ],
)
Example #3
0
    encapsulated-options
        options associated with this Softwire46 Lightweight 4over6 domain.

    The encapsulated-options field conveys options specific to the
    OPTION_S46_CONT_LW option. Currently, there are two options
    specified: OPTION_S46_V4V6BIND and OPTION_S46_BR. There MUST be at
    most one OPTION_S46_V4V6BIND option and at least one OPTION_S46_BR
    option.
    """

    option_type = OPTION_S46_CONT_LW


# Register where these options may occur
SolicitMessage.add_may_contain(S46ContainerOption)
AdvertiseMessage.add_may_contain(S46ContainerOption)
RequestMessage.add_may_contain(S46ContainerOption)
ConfirmMessage.add_may_contain(S46ContainerOption)
RenewMessage.add_may_contain(S46ContainerOption)
RebindMessage.add_may_contain(S46ContainerOption)
ReleaseMessage.add_may_contain(S46ContainerOption)
ReplyMessage.add_may_contain(S46ContainerOption)

S46RuleOption.add_may_contain(S46PortParametersOption)

S46V4V6BindingOption.add_may_contain(S46PortParametersOption)

S46MapEContainerOption.add_may_contain(S46RuleOption, min_occurrence=1)
S46MapEContainerOption.add_may_contain(S46BROption, min_occurrence=1)
S46MapEContainerOption.add_may_contain(S46PortParametersOption)
Example #4
0
        :param length: The amount of data we are allowed to read from the buffer
        :return: The number of bytes used from the buffer
        """
        my_offset, option_len = self.parse_option_header(
            buffer, offset, length)

        if option_len != 4:
            raise ValueError('INF_MAX_RT Options must have length 4')

        self.inf_max_rt = unpack_from('!I', buffer,
                                      offset=offset + my_offset)[0]
        my_offset += 4

        return my_offset

    def save(self) -> Union[bytes, bytearray]:
        """
        Save the internal state of this object as a buffer.

        :return: The buffer with the data from this element
        """
        return pack('!HHI', self.option_type, 4, self.inf_max_rt)


# Register where these options may occur
AdvertiseMessage.add_may_contain(SolMaxRTOption, 0, 1)
ReplyMessage.add_may_contain(SolMaxRTOption, 0, 1)

AdvertiseMessage.add_may_contain(InfMaxRTOption, 0, 1)
ReplyMessage.add_may_contain(InfMaxRTOption, 0, 1)
Example #5
0
        return my_offset

    def save(self) -> bytes:
        """
        Save the internal state of this object as a buffer.

        :return: The buffer with the data from this element
        """
        self.validate()

        options_buffer = bytearray()
        for option in self.options:
            options_buffer.extend(option.save())

        buffer = bytearray()
        buffer.extend(pack('!HH', self.option_type, len(options_buffer)))
        buffer.extend(options_buffer)
        return buffer


# Register where these options may occur
SolicitMessage.add_may_contain(NTPServersOption)
AdvertiseMessage.add_may_contain(NTPServersOption)
RequestMessage.add_may_contain(NTPServersOption)
RenewMessage.add_may_contain(NTPServersOption)
RebindMessage.add_may_contain(NTPServersOption)
InformationRequestMessage.add_may_contain(NTPServersOption)
ReplyMessage.add_may_contain(NTPServersOption)

NTPServersOption.add_may_contain(NTPSubOption, 1)
Example #6
0
        """
        Save the internal state of this object as a buffer.

        :return: The buffer with the data from this element
        """
        buffer = bytearray()
        buffer.extend(pack('!HH', self.option_type,
                           len(self.sip_servers) * 16))
        for address in self.sip_servers:
            buffer.extend(address.packed)

        return buffer


# Register where these options may occur
SolicitMessage.add_may_contain(SIPServersDomainNameListOption)
AdvertiseMessage.add_may_contain(SIPServersDomainNameListOption)
RequestMessage.add_may_contain(SIPServersDomainNameListOption)
RenewMessage.add_may_contain(SIPServersDomainNameListOption)
RebindMessage.add_may_contain(SIPServersDomainNameListOption)
InformationRequestMessage.add_may_contain(SIPServersDomainNameListOption)
ReplyMessage.add_may_contain(SIPServersDomainNameListOption)

SolicitMessage.add_may_contain(SIPServersAddressListOption)
AdvertiseMessage.add_may_contain(SIPServersAddressListOption)
RequestMessage.add_may_contain(SIPServersAddressListOption)
RenewMessage.add_may_contain(SIPServersAddressListOption)
RebindMessage.add_may_contain(SIPServersAddressListOption)
InformationRequestMessage.add_may_contain(SIPServersAddressListOption)
ReplyMessage.add_may_contain(SIPServersAddressListOption)
Example #7
0
        :param offset: The offset in the buffer where to start reading
        :param length: The amount of data we are allowed to read from the buffer
        :return: The number of bytes used from the buffer
        """
        my_offset, option_len = self.parse_option_header(buffer, offset, length)

        if option_len != 4:
            raise ValueError('INF_MAX_RT Options must have length 4')

        self.inf_max_rt = unpack_from('!I', buffer, offset=offset + my_offset)
        my_offset += 4

        self.validate()

        return my_offset

    def save(self) -> bytes:
        """
        Save the internal state of this object as a buffer.

        :return: The buffer with the data from this element
        """
        self.validate()
        return pack('!HHI', self.option_type, 4, self.inf_max_rt)


AdvertiseMessage.add_may_contain(SolMaxRTOption)
AdvertiseMessage.add_may_contain(InfMaxRTOption)
ReplyMessage.add_may_contain(SolMaxRTOption)
ReplyMessage.add_may_contain(InfMaxRTOption)
Example #8
0
        """
        Save the internal state of this object as a buffer.

        :return: The buffer with the data from this element
        """
        self.validate()

        domain_buffer = encode_domain_list(self.search_list)

        buffer = bytearray()
        buffer.extend(pack('!HH', self.option_type, len(domain_buffer)))
        buffer.extend(domain_buffer)
        return buffer


SolicitMessage.add_may_contain(RecursiveNameServersOption, 0, 1)
AdvertiseMessage.add_may_contain(RecursiveNameServersOption, 0, 1)
RequestMessage.add_may_contain(RecursiveNameServersOption, 0, 1)
RenewMessage.add_may_contain(RecursiveNameServersOption, 0, 1)
RebindMessage.add_may_contain(RecursiveNameServersOption, 0, 1)
InformationRequestMessage.add_may_contain(RecursiveNameServersOption, 0, 1)
ReplyMessage.add_may_contain(RecursiveNameServersOption, 0, 1)

SolicitMessage.add_may_contain(DomainSearchListOption, 0, 1)
AdvertiseMessage.add_may_contain(DomainSearchListOption, 0, 1)
RequestMessage.add_may_contain(DomainSearchListOption, 0, 1)
RenewMessage.add_may_contain(DomainSearchListOption, 0, 1)
RebindMessage.add_may_contain(DomainSearchListOption, 0, 1)
InformationRequestMessage.add_may_contain(DomainSearchListOption, 0, 1)
ReplyMessage.add_may_contain(DomainSearchListOption, 0, 1)
        :param buffer: The buffer to read data from
        :param offset: The offset in the buffer where to start reading
        :param length: The amount of data we are allowed to read from the buffer
        :return: The number of bytes used from the buffer
        """
        my_offset, option_len = self.parse_option_header(buffer, offset, length)

        if option_len != 4:
            raise ValueError("SOL_MAX_RT Options must have length 4")

        self.sol_max_rt = unpack_from("!I", buffer, offset=offset + my_offset)[0]
        my_offset += 4

        self.validate()

        return my_offset

    def save(self) -> bytes:
        """
        Save the internal state of this object as a buffer.

        :return: The buffer with the data from this element
        """
        self.validate()
        return pack("!HHI", self.option_type, 4, self.sol_max_rt)


AdvertiseMessage.add_may_contain(SolMaxRTTechnicolorOption)
ReplyMessage.add_may_contain(SolMaxRTTechnicolorOption)
Example #10
0
    encapsulated-options
        options associated with this Softwire46 Lightweight 4over6 domain.

    The encapsulated-options field conveys options specific to the
    OPTION_S46_CONT_LW option. Currently, there are two options
    specified: OPTION_S46_V4V6BIND and OPTION_S46_BR. There MUST be at
    most one OPTION_S46_V4V6BIND option and at least one OPTION_S46_BR
    option.
    """

    option_type = OPTION_S46_CONT_LW


# Register where these options may occur
SolicitMessage.add_may_contain(S46ContainerOption)
AdvertiseMessage.add_may_contain(S46ContainerOption)
RequestMessage.add_may_contain(S46ContainerOption)
ConfirmMessage.add_may_contain(S46ContainerOption)
RenewMessage.add_may_contain(S46ContainerOption)
RebindMessage.add_may_contain(S46ContainerOption)
ReleaseMessage.add_may_contain(S46ContainerOption)
ReplyMessage.add_may_contain(S46ContainerOption)

S46RuleOption.add_may_contain(S46PortParametersOption)

S46V4V6BindingOption.add_may_contain(S46PortParametersOption)

S46MapEContainerOption.add_may_contain(S46RuleOption, min_occurrence=1)
S46MapEContainerOption.add_may_contain(S46BROption, min_occurrence=1)
S46MapEContainerOption.add_may_contain(S46PortParametersOption)
Example #11
0
        :return: The buffer with the data from this element
        """
        options_buffer = bytearray()
        for option in self.options:
            options_buffer.extend(option.save())

        buffer = bytearray()
        buffer.extend(
            pack('!HHIIB', self.option_type,
                 len(options_buffer) + 25, self.preferred_lifetime,
                 self.valid_lifetime, self.prefix.prefixlen))
        buffer.extend(self.prefix.network_address.packed)
        buffer.extend(options_buffer)
        return buffer


# Register where these options may occur
SolicitMessage.add_may_contain(IAPDOption)
AdvertiseMessage.add_may_contain(IAPDOption)
RequestMessage.add_may_contain(IAPDOption)
ConfirmMessage.add_may_contain(IAPDOption)
RenewMessage.add_may_contain(IAPDOption)
RebindMessage.add_may_contain(IAPDOption)
ReleaseMessage.add_may_contain(IAPDOption)
ReplyMessage.add_may_contain(IAPDOption)

IAPDOption.add_may_contain(IAPrefixOption)
IAPDOption.add_may_contain(StatusCodeOption, 0, 1)

IAPrefixOption.add_may_contain(StatusCodeOption, 0, 1)
Example #12
0
        Save the internal state of this object as a buffer.

        :return: The buffer with the data from this element
        """
        self.validate()

        buffer = bytearray()
        buffer.extend(pack('!HH', self.option_type, len(self.sip_servers) * 16))
        for address in self.sip_servers:
            buffer.extend(address.packed)

        return buffer


# Register where these options may occur
SolicitMessage.add_may_contain(SIPServersDomainNameListOption)
AdvertiseMessage.add_may_contain(SIPServersDomainNameListOption)
RequestMessage.add_may_contain(SIPServersDomainNameListOption)
RenewMessage.add_may_contain(SIPServersDomainNameListOption)
RebindMessage.add_may_contain(SIPServersDomainNameListOption)
InformationRequestMessage.add_may_contain(SIPServersDomainNameListOption)
ReplyMessage.add_may_contain(SIPServersDomainNameListOption)

SolicitMessage.add_may_contain(SIPServersAddressListOption)
AdvertiseMessage.add_may_contain(SIPServersAddressListOption)
RequestMessage.add_may_contain(SIPServersAddressListOption)
RenewMessage.add_may_contain(SIPServersAddressListOption)
RebindMessage.add_may_contain(SIPServersAddressListOption)
InformationRequestMessage.add_may_contain(SIPServersAddressListOption)
ReplyMessage.add_may_contain(SIPServersAddressListOption)
Example #13
0
        :return: The buffer with the data from this element
        """
        self.validate()

        options_buffer = bytearray()
        for option in self.options:
            options_buffer.extend(option.save())

        buffer = bytearray()
        buffer.extend(pack('!HHIIB', self.option_type, len(options_buffer) + 25,
                           self.preferred_lifetime, self.valid_lifetime, self.prefix.prefixlen))
        buffer.extend(self.prefix.network_address.packed)
        buffer.extend(options_buffer)
        return buffer


# Register where these options may occur
SolicitMessage.add_may_contain(IAPDOption)
AdvertiseMessage.add_may_contain(IAPDOption)
RequestMessage.add_may_contain(IAPDOption)
RenewMessage.add_may_contain(IAPDOption)
RebindMessage.add_may_contain(IAPDOption)
ReleaseMessage.add_may_contain(IAPDOption)
ReplyMessage.add_may_contain(IAPDOption)

IAPDOption.add_may_contain(IAPrefixOption)
IAPDOption.add_may_contain(StatusCodeOption, 0, 1)

IAPrefixOption.add_may_contain(StatusCodeOption, 0, 1)
Example #14
0
        max_offset = option_len + header_offset  # The option_len field counts bytes *after* the header fields
        domain_name_len, self.domain_name = parse_domain_bytes(buffer, offset=offset + my_offset, length=option_len - 1,
                                                               allow_relative=True)
        my_offset += domain_name_len

        if my_offset != max_offset:
            raise ValueError('Option length does not match the combined length of the included domain name')

        return my_offset

    def save(self) -> Union[bytes, bytearray]:
        """
        Save the internal state of this object as a buffer.

        :return: The buffer with the data from this element
        """
        domain_buffer = encode_domain(self.domain_name)

        buffer = bytearray()
        buffer.extend(pack('!HHB', self.option_type, 1 + len(domain_buffer), self.flags))
        buffer.extend(domain_buffer)
        return buffer


SolicitMessage.add_may_contain(ClientFQDNOption, 0, 1)
AdvertiseMessage.add_may_contain(ClientFQDNOption, 0, 1)
RequestMessage.add_may_contain(ClientFQDNOption, 0, 1)
RenewMessage.add_may_contain(ClientFQDNOption, 0, 1)
RebindMessage.add_may_contain(ClientFQDNOption, 0, 1)
ReplyMessage.add_may_contain(ClientFQDNOption, 0, 1)
Example #15
0
        max_offset = option_len + header_offset  # The option_len field counts bytes *after* the header fields
        while max_offset > my_offset:
            address = IPv6Address(buffer[offset + my_offset:offset + my_offset + 16])
            self.sntp_servers.append(address)
            my_offset += 16

        return my_offset

    def save(self) -> Union[bytes, bytearray]:
        """
        Save the internal state of this object as a buffer.

        :return: The buffer with the data from this element
        """
        buffer = bytearray()
        buffer.extend(pack('!HH', self.option_type, len(self.sntp_servers) * 16))
        for address in self.sntp_servers:
            buffer.extend(address.packed)

        return buffer


# Register where these options may occur
SolicitMessage.add_may_contain(SNTPServersOption)
AdvertiseMessage.add_may_contain(SNTPServersOption)
RequestMessage.add_may_contain(SNTPServersOption)
RenewMessage.add_may_contain(SNTPServersOption)
RebindMessage.add_may_contain(SNTPServersOption)
InformationRequestMessage.add_may_contain(SNTPServersOption)
ReplyMessage.add_may_contain(SNTPServersOption)
Example #16
0
    def save(self) -> Union[bytes, bytearray]:
        """
        Save the internal state of this object as a buffer.

        :return: The buffer with the data from this element
        """
        domain_buffer = encode_domain_list(self.search_list)

        buffer = bytearray()
        buffer.extend(pack('!HH', self.option_type, len(domain_buffer)))
        buffer.extend(domain_buffer)
        return buffer


# Register where these options may occur
SolicitMessage.add_may_contain(RecursiveNameServersOption)
AdvertiseMessage.add_may_contain(RecursiveNameServersOption)
RequestMessage.add_may_contain(RecursiveNameServersOption)
RenewMessage.add_may_contain(RecursiveNameServersOption)
RebindMessage.add_may_contain(RecursiveNameServersOption)
InformationRequestMessage.add_may_contain(RecursiveNameServersOption)
ReplyMessage.add_may_contain(RecursiveNameServersOption)

SolicitMessage.add_may_contain(DomainSearchListOption)
AdvertiseMessage.add_may_contain(DomainSearchListOption)
RequestMessage.add_may_contain(DomainSearchListOption)
RenewMessage.add_may_contain(DomainSearchListOption)
RebindMessage.add_may_contain(DomainSearchListOption)
InformationRequestMessage.add_may_contain(DomainSearchListOption)
ReplyMessage.add_may_contain(DomainSearchListOption)
Example #17
0
        my_offset += name_len

        if my_offset != max_offset:
            raise ValueError(
                'Option length does not match the length of the included fqdn')

        return my_offset

    def save(self) -> Union[bytes, bytearray]:
        """
        Save the internal state of this object as a buffer.

        :return: The buffer with the data from this element
        """
        fqdn_buffer = encode_domain(self.fqdn)

        buffer = bytearray()
        buffer.extend(pack('!HH', self.option_type, len(fqdn_buffer)))
        buffer.extend(fqdn_buffer)
        return buffer


# Update the messages where this option may appear
SolicitMessage.add_may_contain(AFTRNameOption, 0, 1)
AdvertiseMessage.add_may_contain(AFTRNameOption, 0, 1)
RequestMessage.add_may_contain(AFTRNameOption, 0, 1)
RenewMessage.add_may_contain(AFTRNameOption, 0, 1)
RebindMessage.add_may_contain(AFTRNameOption, 0, 1)
InformationRequestMessage.add_may_contain(AFTRNameOption, 0, 1)
ReplyMessage.add_may_contain(AFTRNameOption, 0, 1)
Example #18
0
        return my_offset

    def save(self) -> Union[bytes, bytearray]:
        """
        Save the internal state of this object as a buffer.

        :return: The buffer with the data from this element
        """
        buffer = bytearray()
        buffer.extend(pack('!HH', self.option_type, len(self.timezone)))
        buffer.extend(self.timezone.encode('ascii'))
        return buffer


SolicitMessage.add_may_contain(PosixTimezoneOption, 0, 1)
AdvertiseMessage.add_may_contain(PosixTimezoneOption, 0, 1)
RequestMessage.add_may_contain(PosixTimezoneOption, 0, 1)
RenewMessage.add_may_contain(PosixTimezoneOption, 0, 1)
RebindMessage.add_may_contain(PosixTimezoneOption, 0, 1)
InformationRequestMessage.add_may_contain(PosixTimezoneOption, 0, 1)
ReplyMessage.add_may_contain(PosixTimezoneOption, 0, 1)

SolicitMessage.add_may_contain(TZDBTimezoneOption, 0, 1)
AdvertiseMessage.add_may_contain(TZDBTimezoneOption, 0, 1)
RequestMessage.add_may_contain(TZDBTimezoneOption, 0, 1)
RenewMessage.add_may_contain(TZDBTimezoneOption, 0, 1)
RebindMessage.add_may_contain(TZDBTimezoneOption, 0, 1)
InformationRequestMessage.add_may_contain(TZDBTimezoneOption, 0, 1)
ReplyMessage.add_may_contain(TZDBTimezoneOption, 0, 1)