コード例 #1
0
ファイル: test_model.py プロジェクト: senier/RecordFlux
 def test_message_incoming(self) -> None:
     self.assertEqual(ETHERNET_FRAME.incoming(INITIAL), [])
     self.assertEqual(
         ETHERNET_FRAME.incoming(Field("Type_Length")),
         [
             Link(
                 Field("Type_Length_TPID"),
                 Field("Type_Length"),
                 NotEqual(Variable("Type_Length_TPID"), Number(0x8100, 16)),
                 first=First("Type_Length_TPID"),
             ),
             Link(Field("TCI"), Field("Type_Length")),
         ],
     )
     self.assertEqual(
         ETHERNET_FRAME.incoming(FINAL),
         [
             Link(
                 Field("Payload"),
                 FINAL,
                 And(
                     GreaterEqual(Div(Length("Payload"), Number(8)), Number(46)),
                     LessEqual(Div(Length("Payload"), Number(8)), Number(1500)),
                 ),
             )
         ],
     )
コード例 #2
0
def test_exclusive_with_length_invalid() -> None:
    f1 = Field(ID("F1", Location((98, 10))))
    structure = [
        Link(INITIAL, f1, length=Number(32)),
        Link(f1,
             FINAL,
             condition=Equal(Length("F1"), Number(32), Location((10, 2)))),
        Link(f1,
             Field("F2"),
             condition=Equal(Length("F1"), Number(32), Location((12, 4)))),
        Link(Field("F2"), FINAL),
    ]
    types = {
        Field("F1"): Opaque(),
        Field("F2"): RANGE_INTEGER,
    }
    assert_message_model_error(
        structure,
        types,
        r"^"
        r'<stdin>:98:10: model: error: conflicting conditions for field "F1"\n'
        r"<stdin>:10:2: model: info: condition 0 [(]F1 -> Final[)]: F1\'Length = 32\n"
        r"<stdin>:12:4: model: info: condition 1 [(]F1 -> F2[)]: F1\'Length = 32"
        r"$",
    )
コード例 #3
0
ファイル: model.py プロジェクト: senier/RecordFlux
 def __link_expression(self, link: Link) -> Expr:
     name = link.target.name
     return And(
         *[
             Equal(First(name), self.__target_first(link)),
             Equal(Length(name), self.__target_length(link)),
             Equal(Last(name), self.__target_last(link)),
             GreaterEqual(First("Message"), Number(0)),
             GreaterEqual(Last("Message"), Last(name)),
             GreaterEqual(Last("Message"), First("Message")),
             Equal(Length("Message"), Add(Sub(Last("Message"), First("Message")), Number(1))),
             link.condition,
         ]
     )
コード例 #4
0
def test_valid_use_message_length() -> None:
    structure = [
        Link(INITIAL, Field("Verify_Data"), length=Length("Message")),
        Link(Field("Verify_Data"), FINAL),
    ]
    types = {Field("Verify_Data"): Opaque()}
    Message("P.M", structure, types)
コード例 #5
0
ファイル: typevalue.py プロジェクト: kug1977/RecordFlux
 def assign(self, value: str, check: bool = True) -> None:
     prefixed_value = (
         ID(value) if value.startswith(str(self._type.package))
         or not self.__imported or self.__builtin else self._type.package *
         value)
     if Variable(prefixed_value) not in self.literals:
         raise KeyError(f"{value} is not a valid enum value")
     r = (And(*self._type.constraints(
         "__VALUE__", check, not self.__imported)).substituted(
             mapping={
                 **self.literals,
                 **{
                     Variable("__VALUE__"):
                     self._type.literals[prefixed_value.name]
                 },
                 **{
                     Length("__VALUE__"): self._type.size
                 },
             }).simplified())
     assert r == TRUE
     self._value = (
         str(prefixed_value) if self.__imported and not self.__builtin else
         str(prefixed_value.name),
         self._type.literals[prefixed_value.name],
     )
コード例 #6
0
def enumeration_functions(enum: Enumeration) -> List[Subprogram]:
    common_precondition = And(
        Less(Value('Offset'), Number(8)),
        Equal(
            Length('Buffer'),
            Add(
                Div(Add(Size(enum.base_name), Value('Offset'), Number(-1)),
                    Number(8)), Number(1))))

    control_expression = LogCall(
        f'Convert_To_{enum.base_name} (Buffer, Offset)')

    validation_expression: Expr
    if enum.always_valid:
        validation_expression = Value('True')
    else:
        validation_cases: List[Tuple[Expr, Expr]] = []
        validation_cases.extend(
            (value, Value('True')) for value in enum.literals.values())
        validation_cases.append((Value('others'), Value('False')))

        validation_expression = CaseExpression(control_expression,
                                               validation_cases)
    validation_function = ExpressionFunction(
        f'Valid_{enum.name}', 'Boolean', [('Buffer', 'Types.Bytes'),
                                          ('Offset', 'Natural')],
        validation_expression, [Precondition(common_precondition)])

    function_name = f'Convert_To_{enum.name}'
    parameters = [('Buffer', 'Types.Bytes'), ('Offset', 'Natural')]
    precondition = Precondition(
        And(common_precondition,
            LogCall(f'Valid_{enum.name} (Buffer, Offset)')))
    conversion_cases: List[Tuple[Expr, Expr]] = []
    conversion_function: Subprogram

    if enum.always_valid:
        conversion_cases.extend((value, Aggregate(Value('True'), Value(key)))
                                for key, value in enum.literals.items())
        conversion_cases.append(
            (Value('others'), Aggregate(Value('False'), Value('Raw'))))

        conversion_function = Function(
            function_name, enum.name, parameters,
            [Declaration('Raw', enum.base_name, control_expression)],
            [ReturnStatement(CaseExpression(Value('Raw'), conversion_cases))],
            [precondition])
    else:
        conversion_cases.extend(
            (value, Value(key)) for key, value in enum.literals.items())
        conversion_cases.append(
            (Value('others'), LogCall(f'Unreachable_{enum.name}')))

        conversion_function = ExpressionFunction(
            function_name, enum.name, parameters,
            CaseExpression(control_expression, conversion_cases),
            [precondition])

    return [validation_function, conversion_function]
コード例 #7
0
def create_facts(facts: Dict[Attribute, MathExpr],
                 edge: Edge) -> Dict[Attribute, MathExpr]:
    facts = dict(facts)
    facts[Length(edge.target.name)] = edge.length.simplified(facts)
    facts[First(edge.target.name)] = edge.first.simplified(facts)
    facts[Last(edge.target.name)] = Add(edge.first, edge.length,
                                        Number(-1)).simplified(facts)
    return facts
コード例 #8
0
def parse_attribute(string: str, location: int, tokens: list) -> Attribute:
    if tokens[2] == 'First':
        return First(tokens[0])
    if tokens[2] == 'Last':
        return Last(tokens[0])
    if tokens[2] == 'Length':
        return Length(tokens[0])
    raise ParseFatalException(string, location, 'unexpected attribute')
コード例 #9
0
def parse_attribute(string: str, location: int,
                    tokens: ParseResults) -> Attribute:
    if tokens[2] == "First":
        return First(tokens[0])
    if tokens[2] == "Last":
        return Last(tokens[0])
    if tokens[2] == "Length":
        return Length(tokens[0])
    raise ParseFatalException(string, location, "unexpected attribute")
コード例 #10
0
def buffer_constraints(last: MathExpr) -> LogExpr:
    last = last.simplified()
    index_constraint = LessEqual(First('Buffer'),
                                 Div(Last('Types.Index_Type'), Number(2)))
    if last != Last('Buffer'):
        length_constraint = GreaterEqual(
            Length('Buffer'), Add(last, -First('Buffer'), Number(1)))
        return And(length_constraint, index_constraint)
    return index_constraint
コード例 #11
0
ファイル: typevalue.py プロジェクト: kug1977/RecordFlux
 def assign(self, value: int, check: bool = True) -> None:
     if (And(*self._type.constraints("__VALUE__", check)).substituted(
             mapping={
                 Variable("__VALUE__"): Number(value),
                 Length("__VALUE__"): self._type.size
             }).simplified() != TRUE):
         raise ValueError(
             f"value {value} not in type range {self._first} .. {self._last}"
         )
     self._value = value
コード例 #12
0
ファイル: test_expression.py プロジェクト: kug1977/RecordFlux
def test_attribute() -> None:
    assert isinstance(Size("X"), Attribute)
    assert isinstance(Length("X"), Attribute)
    assert isinstance(First("X"), Attribute)
    assert isinstance(Last("X"), Attribute)
    assert isinstance(Range("X"), Attribute)
    assert isinstance(Old("X"), Attribute)
    assert isinstance(Result("X"), Attribute)
    assert isinstance(Constrained("X"), Attribute)
    assert First("X") == First(Variable("X"))
    assert First("X") == First(ID("X"))
    assert First("X") == First(Variable(ID("X")))
コード例 #13
0
def test_message_invalid_use_of_length_attribute() -> None:
    structure = [
        Link(INITIAL, Field("F1")),
        Link(Field("F1"), FINAL,
             Equal(Length("F1"), Number(32), Location((400, 17)))),
    ]
    types = {Field("F1"): MODULAR_INTEGER}
    assert_message_model_error(
        structure,
        types,
        r'^<stdin>:400:17: model: error: invalid use of length attribute for "F1"$',
    )
コード例 #14
0
ファイル: common.py プロジェクト: senier/RecordFlux
    def substitution(self, message: Message, prefix: bool = True) -> Mapping[Name, Expr]:
        def prefixed(name: str) -> Expr:
            return Selected(Name("Ctx"), name) if prefix else Name(name)

        first = prefixed("First")
        last = prefixed("Last")
        cursors = prefixed("Cursors")

        return {
            **{First("Message"): first},
            **{Last("Message"): last},
            **{
                First(f.name): Selected(Indexed(cursors, Name(f.affixed_name)), "First")
                for f in message.fields
            },
            **{
                Last(f.name): Selected(Indexed(cursors, Name(f.affixed_name)), "Last")
                for f in message.fields
            },
            **{
                Length(f.name): Add(
                    Sub(
                        Selected(Indexed(cursors, Name(f.affixed_name)), "Last"),
                        Selected(Indexed(cursors, Name(f.affixed_name)), "First"),
                    ),
                    Number(1),
                )
                for f in message.fields
            },
            **{
                Variable(f.name): Call(
                    self.types.bit_length,
                    [Selected(Indexed(cursors, Name(f.affixed_name)), f"Value.{f.name}_Value")],
                )
                for f, t in message.types.items()
                if not isinstance(t, Enumeration)
            },
            **{
                Variable(f.name): Call(
                    self.types.bit_length,
                    [Selected(Indexed(cursors, Name(f.affixed_name)), f"Value.{f.name}_Value")],
                )
                for f, t in message.types.items()
                if isinstance(t, Enumeration)
            },
            **{
                Variable(l): Call(self.types.bit_length, [Call("Convert", [Name(l)])])
                for l in itertools.chain.from_iterable(
                    t.literals.keys() for t in message.types.values() if isinstance(t, Enumeration)
                )
            },
        }
コード例 #15
0
def test_exclusive_with_length_valid() -> None:
    structure = [
        Link(INITIAL, Field("F1"), length=Number(32)),
        Link(
            Field("F1"),
            FINAL,
            condition=And(Equal(Length("F1"), Number(32)),
                          Less(Variable("F1"), Number(50))),
        ),
        Link(
            Field("F1"),
            Field("F2"),
            condition=And(Equal(Length("F1"), Number(32)),
                          Greater(Variable("F1"), Number(80))),
        ),
        Link(Field("F2"), FINAL),
    ]
    types = {
        Field("F1"): Opaque(),
        Field("F2"): MODULAR_INTEGER,
    }
    Message("P.M", structure, types)
コード例 #16
0
def create_ethernet_pdu() -> PDU:
    uint48 = ModularInteger('UINT48', Pow(Number(2), Number(48)))
    uint16 = RangeInteger('UINT16',
                          Number(0),
                          Sub(Pow(Number(2), Number(16)), Number(1)),
                          Number(16))
    payload_array = Array('Payload_Array')

    initial = InitialNode()
    destination = Node('Destination', uint48)
    source = Node('Source', uint48)
    tpid = Node('TPID', uint16)
    tci = Node('TCI', uint16)
    ether_type = Node('EtherType', uint16)
    payload = Node('Payload', payload_array)

    initial.edges = [Edge(destination)]
    destination.edges = [Edge(source)]
    source.edges = [Edge(tpid)]
    tpid.edges = [Edge(tci,
                       Equal(Value('TPID'), Number(0x8100))),
                  Edge(ether_type,
                       NotEqual(Value('TPID'), Number(0x8100)),
                       first=First('TPID'))]
    tci.edges = [Edge(ether_type)]
    ether_type.edges = [Edge(payload,
                             LessEqual(Value('EtherType'), Number(1500)),
                             Mul(LengthValue('EtherType'), Number(8))),
                        Edge(payload,
                             GreaterEqual(Value('EtherType'), Number(1536)),
                             Sub(Last('Message'), Last('EtherType')))]
    payload.edges = [Edge(FINAL,
                          And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)),
                              LessEqual(Div(Length('Payload'), Number(8)), Number(1500))))]

    return PDU('Ethernet.Frame', initial)
コード例 #17
0
ファイル: typevalue.py プロジェクト: kug1977/RecordFlux
 def __update_simplified_mapping(self) -> None:
     field_values: Mapping[Name, Expr] = {
         **{
             Variable(k): v.typeval.expr
             for k, v in self._fields.items() if isinstance(
                 v.typeval, ScalarValue) and v.set
         },
         **{
             Length(k): v.typeval.size
             for k, v in self._fields.items() if v.set
         },
         **{First(k): v.first
            for k, v in self._fields.items() if v.set},
         **{Last(k): v.last
            for k, v in self._fields.items() if v.set},
     }
     self._simplified_mapping = {**field_values, **self.__type_literals}
コード例 #18
0
ファイル: common.py プロジェクト: senier/RecordFlux
 def public_substitution(self, message: Message) -> Mapping[Name, Expr]:
     return {
         **{First("Message"): Selected(Name("Ctx"), "First")},
         **{Last("Message"): Selected(Name("Ctx"), "Last")},
         **{
             First(f.name): Call("Field_First", [Name("Ctx"), Name(f.affixed_name)])
             for f in message.fields
         },
         **{
             Last(f.name): Call("Field_Last", [Name("Ctx"), Name(f.affixed_name)])
             for f in message.fields
         },
         **{
             Length(f.name): Call("Field_Length", [Name("Ctx"), Name(f.affixed_name)])
             for f in message.fields
         },
         **{
             Variable(f.name): Call(
                 self.types.bit_length, [Call(f"Get_{f.name}", [Name("Ctx")])]
             )
             for f, t in message.types.items()
             if not isinstance(t, Enumeration)
         },
         **{
             Variable(f.name): Call(
                 self.types.bit_length, [Call("Convert", [Call(f"Get_{f.name}", [Name("Ctx")])])]
             )
             for f, t in message.types.items()
             if isinstance(t, Enumeration)
         },
         **{
             Variable(l): Call(self.types.bit_length, [Call("Convert", [Name(l)])])
             for l in itertools.chain.from_iterable(
                 t.literals.keys() for t in message.types.values() if isinstance(t, Enumeration)
             )
         },
     }
コード例 #19
0
    def __process_pdus(self, pdus: List[PDU]) -> None:
        seen_types: List[str] = []

        for pdu in pdus:
            if pdu.package not in self.__units:
                self.__units[pdu.package] = Unit(COMMON_CONTEXT,
                                                 Package(pdu.package, [], []))

            context: List[ContextItem] = []
            package = Package(pdu.full_name, [], [])
            self.__units[pdu.full_name] = Unit(context, package)

            package.subprograms.extend(contain_functions())

            facts: Dict[Attribute, MathExpr] = {
                First('Message'):
                Mul(First('Buffer'), Number(8)),
                Last('Message'):
                Mul(Last('Buffer'), Number(8)),
                Length('Message'):
                Sub(Add(Mul(Last('Buffer'), Number(8)), Number(8)),
                    Mul(First('Buffer'), Number(8)))
            }

            fields = pdu.fields(facts, First('Buffer'))
            self.__pdu_fields[pdu.full_name] = list(fields.keys())

            for field in fields.values():
                if field.name == 'FINAL':
                    continue

                if f'{pdu.package}.{field.type.name}' not in seen_types:
                    seen_types.append(f'{pdu.package}.{field.type.name}')

                    self.__create_type(field.type, pdu.package)

                if isinstance(field.type,
                              Array) and 'Payload' not in field.type.name:
                    with_clause = WithClause(
                        [f'{pdu.package}.{field.type.name}'])
                    if with_clause not in context:
                        context.append(with_clause)

                for variant_id, variant in field.variants.items():
                    package.subprograms.append(
                        variant_validation_function(field, variant_id,
                                                    variant))

                    package.subprograms.extend(
                        variant_accessor_functions(field, variant_id, variant))

                package.subprograms.append(field_validation_function(field))

                package.subprograms.extend(
                    field_accessor_functions(field, pdu.package))

            package.subprograms.append(
                message_validation_function(
                    list(fields['FINAL'].variants.values())))

            package.subprograms.append(
                message_length_function(list(
                    fields['FINAL'].variants.values())))

        self.__create_unreachable_functions(pdus)
コード例 #20
0
    def test_pdu_fields_length_after_payload(self) -> None:
        int_type = ModularInteger('T', Number(256))
        payload_type = Array('Payload_Type')

        initial = InitialNode()
        version = Node('Version', int_type)
        payload = Node('Payload', payload_type)
        length = Node('Length', int_type)

        initial.edges = [Edge(version, TRUE)]
        version.edges = [Edge(payload, length=Value('Length'))]
        payload.edges = [Edge(length, first=Add(Last('Buffer'),
                                                -Length('Length'),
                                                Number(1)))]
        length.edges = [Edge(FINAL)]

        pdu = PDU('Foo', initial)

        expected = OrderedDict([
            ('Version',
             Field('Version',
                   int_type,
                   TRUE,
                   {
                       '0':
                       Variant(
                           [],
                           TRUE,
                           {
                               Length('Version'): Number(8),
                               First('Version'): Number(0),
                               Last('Version'): Number(7)
                           })
                   })),
            ('Payload',
             Field('Payload',
                   payload_type,
                   TRUE,
                   {
                       '00':
                       Variant(
                           [('Version', '0')],
                           TRUE,
                           {
                               Length('Version'): Number(8),
                               First('Version'): Number(0),
                               Last('Version'): Number(7),
                               Length('Payload'): Value('Length'),
                               First('Payload'): Number(8),
                               Last('Payload'): Add(Value('Length'), Number(7))
                           })
                   })),
            ('Length',
             Field('Length',
                   int_type,
                   TRUE,
                   {
                       '000':
                       Variant(
                           [('Version', '0'),
                            ('Payload', '00')],
                           TRUE,
                           {
                               Length('Version'): Number(8),
                               First('Version'): Number(0),
                               Last('Version'): Number(7),
                               Length('Payload'): Value('Length'),
                               First('Payload'): Number(8),
                               Last('Payload'): Add(Value('Length'), Number(7)),
                               Length('Length'): Number(8),
                               First('Length'): Add(Last('Buffer'), Number(-7)),
                               Last('Length'): Last('Buffer')
                           })
                   })),
            ('FINAL',
             Field('FINAL',
                   Null(),
                   TRUE,
                   {
                       '0000':
                       Variant(
                           [('Version', '0'),
                            ('Payload', '00'),
                            ('Length', '000')],
                           TRUE,
                           {
                               Length('Version'): Number(8),
                               First('Version'): Number(0),
                               Last('Version'): Number(7),
                               Length('Payload'): Value('Length'),
                               First('Payload'): Number(8),
                               Last('Payload'): Add(Value('Length'), Number(7)),
                               Length('Length'): Number(8),
                               First('Length'): Add(Last('Buffer'), Number(-7)),
                               Last('Length'): Last('Buffer')
                           })
                   }))
        ])

        self.assertEqual(pdu.fields(), expected)
コード例 #21
0
ファイル: models.py プロジェクト: senier/RecordFlux
def create_ethernet_frame() -> Message:
    address_type = ModularInteger("Ethernet.Address",
                                  Pow(Number(2), Number(48)))
    type_length_type = RangeInteger("Ethernet.Type_Length", Number(46),
                                    Sub(Pow(Number(2), Number(16)), Number(1)),
                                    Number(16))
    tpid_type = RangeInteger("Ethernet.TPID", Number(0x8100, 16),
                             Number(0x8100, 16), Number(16))
    tci_type = ModularInteger("Ethernet.TCI", Pow(Number(2), Number(16)))

    structure = [
        Link(INITIAL, Field("Destination")),
        Link(Field("Destination"), Field("Source")),
        Link(Field("Source"), Field("Type_Length_TPID")),
        Link(
            Field("Type_Length_TPID"),
            Field("TPID"),
            Equal(Variable("Type_Length_TPID"), Number(0x8100, 16)),
            first=First("Type_Length_TPID"),
        ),
        Link(
            Field("Type_Length_TPID"),
            Field("Type_Length"),
            NotEqual(Variable("Type_Length_TPID"), Number(0x8100, 16)),
            first=First("Type_Length_TPID"),
        ),
        Link(Field("TPID"), Field("TCI")),
        Link(Field("TCI"), Field("Type_Length")),
        Link(
            Field("Type_Length"),
            Field("Payload"),
            LessEqual(Variable("Type_Length"), Number(1500)),
            Mul(Variable("Type_Length"), Number(8)),
        ),
        Link(
            Field("Type_Length"),
            Field("Payload"),
            GreaterEqual(Variable("Type_Length"), Number(1536)),
            Sub(Last("Message"), Last("Type_Length")),
        ),
        Link(
            Field("Payload"),
            FINAL,
            And(
                GreaterEqual(Div(Length("Payload"), Number(8)), Number(46)),
                LessEqual(Div(Length("Payload"), Number(8)), Number(1500)),
            ),
        ),
    ]

    types = {
        Field("Destination"): address_type,
        Field("Source"): address_type,
        Field("Type_Length_TPID"): type_length_type,
        Field("TPID"): tpid_type,
        Field("TCI"): tci_type,
        Field("Type_Length"): type_length_type,
        Field("Payload"): Payload(),
    }

    return Message("Ethernet.Frame", structure, types)
コード例 #22
0
ファイル: test_expression.py プロジェクト: senier/RecordFlux
 def test_length_z3variables(self) -> None:
     self.assertEqual(Length("Z").variables(True), [Variable("Z'Length")])
コード例 #23
0
ファイル: test_expression.py プロジェクト: kug1977/RecordFlux
def test_length_z3variables() -> None:
    assert Length("Z").variables() == [Variable("Z")]
コード例 #24
0
ファイル: test_parser.py プロジェクト: kug1977/RecordFlux
def test_ethernet_spec() -> None:
    spec = {
        "Ethernet": Specification(
            ContextSpec([]),
            PackageSpec(
                "Ethernet",
                [
                    ModularInteger("__PACKAGE__.Address", Pow(Number(2), Number(48))),
                    RangeInteger(
                        "__PACKAGE__.Type_Length",
                        Number(46),
                        Sub(Pow(Number(2), Number(16)), Number(1)),
                        Number(16),
                    ),
                    RangeInteger(
                        "__PACKAGE__.TPID", Number(0x8100, 16), Number(0x8100, 16), Number(16)
                    ),
                    ModularInteger("__PACKAGE__.TCI", Pow(Number(2), Number(16))),
                    MessageSpec(
                        "__PACKAGE__.Frame",
                        [
                            Component("Destination", "Address"),
                            Component("Source", "Address"),
                            Component(
                                "Type_Length_TPID",
                                "Type_Length",
                                [
                                    Then(
                                        "TPID",
                                        First("Type_Length_TPID"),
                                        UNDEFINED,
                                        Equal(Variable("Type_Length_TPID"), Number(33024, 16)),
                                    ),
                                    Then(
                                        "Type_Length",
                                        First("Type_Length_TPID"),
                                        UNDEFINED,
                                        NotEqual(Variable("Type_Length_TPID"), Number(33024, 16)),
                                    ),
                                ],
                            ),
                            Component("TPID", "TPID"),
                            Component("TCI", "TCI"),
                            Component(
                                "Type_Length",
                                "Type_Length",
                                [
                                    Then(
                                        "Payload",
                                        UNDEFINED,
                                        Mul(Variable("Type_Length"), Number(8)),
                                        LessEqual(Variable("Type_Length"), Number(1500)),
                                    ),
                                    Then(
                                        "Payload",
                                        UNDEFINED,
                                        Sub(Last("Message"), Last("Type_Length")),
                                        GreaterEqual(Variable("Type_Length"), Number(1536)),
                                    ),
                                ],
                            ),
                            Component(
                                "Payload",
                                "Opaque",
                                [
                                    Then(
                                        condition=And(
                                            GreaterEqual(
                                                Div(Length("Payload"), Number(8)), Number(46),
                                            ),
                                            LessEqual(
                                                Div(Length("Payload"), Number(8)), Number(1500),
                                            ),
                                        ),
                                    )
                                ],
                            ),
                        ],
                    ),
                ],
            ),
        )
    }

    assert_specifications_files([f"{SPECDIR}/ethernet.rflx"], spec)
コード例 #25
0
def substitution_facts(
    message: Message,
    embedded: bool = False,
    public: bool = False,
    target_type: ID = const.TYPES_U64,
) -> Mapping[Name, Expr]:
    def prefixed(name: str) -> Expr:
        return Variable(f"Ctx.{name}") if not embedded else Variable(name)

    first = prefixed("First")
    last = prefixed("Last")
    cursors = prefixed("Cursors")

    def field_first(field: Field) -> Expr:
        if public:
            return Call("Field_First", [Variable("Ctx"), Variable(field.affixed_name)])
        return Selected(Indexed(cursors, Variable(field.affixed_name)), "First")

    def field_last(field: Field) -> Expr:
        if public:
            return Call("Field_Last", [Variable("Ctx"), Variable(field.affixed_name)])
        return Selected(Indexed(cursors, Variable(field.affixed_name)), "Last")

    def field_length(field: Field) -> Expr:
        if public:
            return Call("Field_Length", [Variable("Ctx"), Variable(field.affixed_name)])
        return Add(
            Sub(
                Selected(Indexed(cursors, Variable(field.affixed_name)), "Last"),
                Selected(Indexed(cursors, Variable(field.affixed_name)), "First"),
            ),
            Number(1),
        )

    def field_value(field: Field, field_type: Type) -> Expr:
        if isinstance(field_type, Enumeration):
            if public:
                return Call(
                    target_type, [Call("To_Base", [Call(f"Get_{field.name}", [Variable("Ctx")])])],
                )
            return Call(
                target_type,
                [
                    Selected(
                        Indexed(cursors, Variable(field.affixed_name)), f"Value.{field.name}_Value"
                    )
                ],
            )
        if isinstance(field_type, Scalar):
            if public:
                return Call(target_type, [Call(f"Get_{field.name}", [Variable("Ctx")])])
            return Call(
                target_type,
                [
                    Selected(
                        Indexed(cursors, Variable(field.affixed_name)), f"Value.{field.name}_Value"
                    )
                ],
            )
        if isinstance(field_type, Composite):
            return Variable(field.name)
        assert False, f'unexpected type "{type(field_type).__name__}"'
        return UNDEFINED

    return {
        **{First("Message"): first},
        **{Last("Message"): last},
        **{Length("Message"): Add(last, -first, Number(1))},
        **{First(f.name): field_first(f) for f in message.fields},
        **{Last(f.name): field_last(f) for f in message.fields},
        **{Length(f.name): field_length(f) for f in message.fields},
        **{Variable(f.name): field_value(f, t) for f, t in message.types.items()},
        **{
            Variable(l): Call(target_type, [Call("To_Base", [Variable(l)])])
            for t in message.types.values()
            if isinstance(t, Enumeration)
            for l in t.literals.keys()
        },
        **{
            Variable(t.package * l): Call(target_type, [Call("To_Base", [Variable(t.package * l)])])
            for t in message.types.values()
            if isinstance(t, Enumeration)
            for l in t.literals.keys()
        },
    }
コード例 #26
0
            Field("Type_Length"),
            Field("Payload"),
            LessEqual(Variable("Type_Length"), Number(1500)),
            Mul(Variable("Type_Length"), Number(8)),
        ),
        Link(
            Field("Type_Length"),
            Field("Payload"),
            GreaterEqual(Variable("Type_Length"), Number(1536)),
            Sub(Last("Message"), Last("Type_Length")),
        ),
        Link(
            Field("Payload"),
            FINAL,
            And(
                GreaterEqual(Div(Length("Payload"), Number(8)), Number(46)),
                LessEqual(Div(Length("Payload"), Number(8)), Number(1500)),
            ),
        ),
    ],
    {
        Field("Destination"): ETHERNET_ADDRESS,
        Field("Source"): ETHERNET_ADDRESS,
        Field("Type_Length_TPID"): ETHERNET_TYPE_LENGTH,
        Field("TPID"): ETHERNET_TPID,
        Field("TCI"): ETHERNET_TCI,
        Field("Type_Length"): ETHERNET_TYPE_LENGTH,
        Field("Payload"): Opaque(),
    },
)
ETHERNET_MODEL = Model([
コード例 #27
0
    def test_pdu_fields_ethernet(self) -> None:
        expected = OrderedDict([
            ('Destination',
             Field('Destination',
                   ModularInteger('UINT48', Pow(Number(2), Number(48))),
                   TRUE,
                   {
                       '0':
                       Variant(
                           [],
                           TRUE,
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47)
                           })
                   })),
            ('Source',
             Field('Source',
                   ModularInteger('UINT48', Pow(Number(2), Number(48))),
                   TRUE,
                   {
                       '00':
                       Variant(
                           [
                               ('Destination', '0')
                           ],
                           TRUE,
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95)
                           })
                   })),
            ('TPID',
             Field('TPID',
                   RangeInteger('UINT16',
                                Number(0),
                                Sub(Pow(Number(2), Number(16)), Number(1)),
                                Number(16)),
                   Or(NotEqual(Value('TPID'), Number(0x8100)),
                      Equal(Value('TPID'), Number(0x8100))),
                   {
                       '000':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00')
                           ],
                           TRUE,
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111)
                           })
                   })),
            ('TCI',
             Field('TCI',
                   RangeInteger('UINT16',
                                Number(0),
                                Sub(Pow(Number(2), Number(16)), Number(1)),
                                Number(16)),
                   TRUE,
                   {
                       '0000':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000')
                           ],
                           Equal(Value('TPID'), Number(0x8100)),
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('TCI'): Number(16),
                               First('TCI'): Number(112),
                               Last('TCI'): Number(127)
                           })
                   })),
            ('EtherType',
             Field('EtherType',
                   RangeInteger('UINT16',
                                Number(0),
                                Sub(Pow(Number(2), Number(16)), Number(1)),
                                Number(16)),
                   Or(GreaterEqual(Value('EtherType'), Number(1536)),
                      LessEqual(Value('EtherType'), Number(1500))),
                   {
                       '00000':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000'),
                               ('TCI', '0000')
                           ],
                           TRUE,
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('TCI'): Number(16),
                               First('TCI'): Number(112),
                               Last('TCI'): Number(127),
                               Length('EtherType'): Number(16),
                               First('EtherType'): Number(128),
                               Last('EtherType'): Number(143)
                           }),
                       '0001':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000')
                           ],
                           NotEqual(Value('TPID'), Number(0x8100)),
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('EtherType'): Number(16),
                               First('EtherType'): Number(96),
                               Last('EtherType'): Number(111)
                           })
                   })),
            ('Payload',
             Field('Payload',
                   Array('Payload_Array'),
                   And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)),
                       LessEqual(Div(Length('Payload'), Number(8)), Number(1500))),
                   {
                       '000000':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000'),
                               ('TCI', '0000'),
                               ('EtherType', '00000')
                           ],
                           LessEqual(Value('EtherType'), Number(1500)),
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('TCI'): Number(16),
                               First('TCI'): Number(112),
                               Last('TCI'): Number(127),
                               Length('EtherType'): Number(16),
                               First('EtherType'): Number(128),
                               Last('EtherType'): Number(143),
                               Length('Payload'): Mul(LengthValue('EtherType'), Number(8)),
                               First('Payload'): Number(144),
                               Last('Payload'): Add(Mul(LengthValue('EtherType'), Number(8)),
                                                    Number(143))
                           }),
                       '000001':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000'),
                               ('TCI', '0000'),
                               ('EtherType', '00000')
                           ],
                           GreaterEqual(Value('EtherType'), Number(1536)),
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('TCI'): Number(16),
                               First('TCI'): Number(112),
                               Last('TCI'): Number(127),
                               Length('EtherType'): Number(16),
                               First('EtherType'): Number(128),
                               Last('EtherType'): Number(143),
                               Length('Payload'): Add(Last('Message'), Number(-143)),
                               First('Payload'): Number(144),
                               Last('Payload'): Last('Message')
                           }),
                       '00010':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000'),
                               ('EtherType', '0001')
                           ],
                           LessEqual(Value('EtherType'), Number(1500)),
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('EtherType'): Number(16),
                               First('EtherType'): Number(96),
                               Last('EtherType'): Number(111),
                               Length('Payload'): Mul(LengthValue('EtherType'), Number(8)),
                               First('Payload'): Number(112),
                               Last('Payload'): Add(Mul(LengthValue('EtherType'), Number(8)),
                                                    Number(111))
                           }),
                       '00011':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000'),
                               ('EtherType', '0001')
                           ],
                           GreaterEqual(Value('EtherType'), Number(1536)),
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('EtherType'): Number(16),
                               First('EtherType'): Number(96),
                               Last('EtherType'): Number(111),
                               Length('Payload'): Add(Last('Message'), Number(-111)),
                               First('Payload'): Number(112),
                               Last('Payload'): Last('Message')
                           })
                   })),
            ('FINAL',
             Field('FINAL',
                   Null(),
                   TRUE,
                   {
                       '0000000':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000'),
                               ('TCI', '0000'),
                               ('EtherType', '00000'),
                               ('Payload', '000000')
                           ],
                           And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)),
                               LessEqual(Div(Length('Payload'), Number(8)), Number(1500))),
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('TCI'): Number(16),
                               First('TCI'): Number(112),
                               Last('TCI'): Number(127),
                               Length('EtherType'): Number(16),
                               First('EtherType'): Number(128),
                               Last('EtherType'): Number(143),
                               Length('Payload'): Mul(LengthValue('EtherType'), Number(8)),
                               First('Payload'): Number(144),
                               Last('Payload'): Add(Mul(LengthValue('EtherType'), Number(8)),
                                                    Number(143))
                           }),
                       '0000010':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000'),
                               ('TCI', '0000'),
                               ('EtherType', '00000'),
                               ('Payload', '000001')
                           ],
                           And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)),
                               LessEqual(Div(Length('Payload'), Number(8)), Number(1500))),
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('TCI'): Number(16),
                               First('TCI'): Number(112),
                               Last('TCI'): Number(127),
                               Length('EtherType'): Number(16),
                               First('EtherType'): Number(128),
                               Last('EtherType'): Number(143),
                               Length('Payload'): Add(Last('Message'), Number(-143)),
                               First('Payload'): Number(144),
                               Last('Payload'): Last('Message')
                           }),
                       '000100':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000'),
                               ('EtherType', '0001'),
                               ('Payload', '00010')
                           ],
                           And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)),
                               LessEqual(Div(Length('Payload'), Number(8)), Number(1500))),
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('EtherType'): Number(16),
                               First('EtherType'): Number(96),
                               Last('EtherType'): Number(111),
                               Length('Payload'): Mul(LengthValue('EtherType'), Number(8)),
                               First('Payload'): Number(112),
                               Last('Payload'): Add(Mul(LengthValue('EtherType'), Number(8)),
                                                    Number(111))
                           }),
                       '000110':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000'),
                               ('EtherType', '0001'),
                               ('Payload', '00011')
                           ],
                           And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)),
                               LessEqual(Div(Length('Payload'), Number(8)), Number(1500))),
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('EtherType'): Number(16),
                               First('EtherType'): Number(96),
                               Last('EtherType'): Number(111),
                               Length('Payload'): Add(Last('Message'), Number(-111)),
                               First('Payload'): Number(112),
                               Last('Payload'): Last('Message')
                           })
                   }))
        ])

        self.assertEqual(ETHERNET_PDU.fields(), expected)
コード例 #28
0
 def test_length_simplified(self) -> None:
     self.assertEqual(Length('X').simplified(), Length('X'))
     self.assertEqual(
         Length('X').simplified({Length('X'): Number(42)}), Number(42))
     self.assertEqual(-Length('X').simplified({Length('X'): Number(42)}),
                      Number(-42))