예제 #1
0
 def test_mul_simplified(self) -> None:
     self.assertEqual(
         Mul(Value('X'), Number(2)).simplified(),
         Mul(Value('X'), Number(2)))
     self.assertEqual(Mul(Value('X'), Number(1)).simplified(), Value('X'))
     self.assertEqual(
         Mul(Number(2), Number(3), Number(5)).simplified(), Number(30))
예제 #2
0
 def test_mul(self) -> None:
     self.assertEqual(
         Mul(Number(6), Number(4)).z3expr(),
         z3.IntVal(6) * z3.IntVal(4))
     self.assertEqual(
         Mul(Number(2), Number(4), Number(8)).z3expr(),
         z3.IntVal(2) * z3.IntVal(4) * z3.IntVal(8),
     )
예제 #3
0
 def test_distributivity_simplified(self) -> None:
     self.assertEqual(
         Add(Sub(Value('X'), Add(Value('X'), Number(1))),
             Add(Value('X'), Number(1))).simplified(), Value('X'))
     self.assertEqual(
         Div(Add(Mul(Value('X'), Number(8)), Number(144)),
             Number(8)).simplified(), Add(Value('X'), Number(18)))
     self.assertEqual(
         Div(Sub(Mul(Value('X'), Number(8)), Number(148)),
             Number(8)).simplified(),
         Add(Value('X'), Div(Number(-148), Number(8))))
예제 #4
0
 def test_ass_expr_converted(self) -> None:
     self.assertEqual(
         And(Variable("X"), Number(1)).converted(
             lambda x: Name(x.name) if isinstance(x, Variable) else x
         ),
         And(Name("X"), Number(1)),
     )
     self.assertEqual(
         Mul(Variable("X"), Number(1)).converted(
             lambda x: Name("Y") if x == Mul(Variable("X"), Number(1)) else x
         ),
         Name("Y"),
     )
예제 #5
0
def parse_mathematical_expression(string: str, location: int,
                                  tokens: ParseResults) -> Expr:
    result: List[Expr] = tokens[0]
    while len(result) > 1:
        left = result.pop(0)
        operator = result.pop(0)
        right = result.pop(0)
        assert left.location, f'expression "{left}" without location'
        assert right.location, f'expression "{right}" without location'
        assert left.location.source == right.location.source, "expression with different source"
        locn = Location(left.location.start, left.location.source,
                        left.location.end)
        expression: Expr
        if operator == "+":
            expression = Add(left, right)
            expression.location = locn
        elif operator == "-":
            expression = Sub(left, right, locn)
        elif operator == "*":
            expression = Mul(left, right)
            expression.location = locn
        elif operator == "/":
            expression = Div(left, right, locn)
        elif operator == "**":
            expression = Pow(left, right, locn)
        else:
            raise ParseFatalException(string, location,
                                      "unexpected mathematical operator")
        result.insert(0, expression)
    return result[0]
예제 #6
0
def test_array_type_spec() -> None:
    spec = {
        "Array_Type": Specification(
            ContextSpec([]),
            PackageSpec(
                "Array_Type",
                [
                    ModularInteger("__PACKAGE__.Byte", Number(256)),
                    ArraySpec("__PACKAGE__.Bytes", ReferenceSpec("__PACKAGE__.Byte")),
                    MessageSpec(
                        "__PACKAGE__.Foo",
                        [
                            Component(
                                "Length",
                                "Byte",
                                [Then("Bytes", UNDEFINED, Mul(Variable("Length"), Number(8)))],
                            ),
                            Component("Bytes", "Bytes"),
                        ],
                    ),
                    ArraySpec("__PACKAGE__.Bar", ReferenceSpec("__PACKAGE__.Foo")),
                ],
            ),
        )
    }
    assert_specifications_files([f"{TESTDIR}/array_type.rflx"], spec)
예제 #7
0
파일: models.py 프로젝트: senier/RecordFlux
def create_tlv_message() -> Message:
    tag_type = Enumeration("TLV.Tag", {
        "Msg_Data": Number(1),
        "Msg_Error": Number(3)
    }, Number(2), False)
    length_type = ModularInteger("TLV.Length", Pow(Number(2), Number(14)))

    structure = [
        Link(INITIAL, Field("Tag")),
        Link(Field("Tag"), Field("Length"),
             Equal(Variable("Tag"), Variable("Msg_Data"))),
        Link(Field("Tag"), FINAL, Equal(Variable("Tag"),
                                        Variable("Msg_Error"))),
        Link(Field("Length"),
             Field("Value"),
             length=Mul(Variable("Length"), Number(8))),
        Link(Field("Value"), FINAL),
    ]

    types = {
        Field("Tag"): tag_type,
        Field("Length"): length_type,
        Field("Value"): Payload()
    }

    return Message("TLV.Message", structure, types)
예제 #8
0
 def test_term_simplified(self) -> None:
     self.assertEqual(
         Add(
             Mul(Number(1), Number(6)), Sub(Variable("X"), Number(10)), Add(Number(1), Number(3))
         ).simplified(),
         Variable("X"),
     )
예제 #9
0
파일: models.py 프로젝트: senier/RecordFlux
def create_array_message() -> Message:
    length_type = ModularInteger("Arrays.Length", Pow(Number(2), Number(8)))

    modular_type = ModularInteger("Arrays.Modular_Integer",
                                  Pow(Number(2), Number(16)))
    modular_vector_type = Array("Arrays.Modular_Vector", modular_type)

    range_type = RangeInteger("Arrays.Range_Integer", Number(1), Number(100),
                              Number(8))
    range_vector_type = Array("Arrays.Range_Vector", range_type)

    enum_type = Enumeration(
        "Arrays.Enumeration",
        {
            "ZERO": Number(0),
            "ONE": Number(1),
            "TWO": Number(2)
        },
        Number(8),
        False,
    )
    enum_vector_type = Array("Arrays.Enumeration_Vector", enum_type)

    av_enum_type = Enumeration(
        "Arrays.AV_Enumeration",
        {
            "AV_ZERO": Number(0),
            "AV_ONE": Number(1),
            "AV_TWO": Number(2)
        },
        Number(8),
        True,
    )
    av_enum_vector_type = Array("Arrays.AV_Enumeration_Vector", av_enum_type)

    structure = [
        Link(INITIAL, Field("Length")),
        Link(Field("Length"),
             Field("Modular_Vector"),
             length=Mul(Variable("Length"), Number(8))),
        Link(Field("Modular_Vector"), Field("Range_Vector"),
             length=Number(16)),
        Link(Field("Range_Vector"),
             Field("Enumeration_Vector"),
             length=Number(16)),
        Link(Field("Enumeration_Vector"),
             Field("AV_Enumeration_Vector"),
             length=Number(16)),
        Link(Field("AV_Enumeration_Vector"), FINAL),
    ]

    types = {
        Field("Length"): length_type,
        Field("Modular_Vector"): modular_vector_type,
        Field("Range_Vector"): range_vector_type,
        Field("Enumeration_Vector"): enum_vector_type,
        Field("AV_Enumeration_Vector"): av_enum_vector_type,
    }

    return Message("Arrays.Message", structure, types)
예제 #10
0
 def test_expr_variables_duplicates(self) -> None:
     self.assertEqual(
         And(Variable("X"), Variable("Y"), Variable("X")).variables(),
         [Variable("X"), Variable("Y")],
     )
     self.assertEqual(
         Or(Variable("X"), Variable("Y"), Variable("X")).variables(),
         [Variable("X"), Variable("Y")],
     )
     self.assertEqual(
         Add(Variable("X"), Variable("Y"), Variable("X")).variables(),
         [Variable("X"), Variable("Y")],
     )
     self.assertEqual(
         Mul(Variable("X"), Variable("Y"), Variable("X")).variables(),
         [Variable("X"), Variable("Y")],
     )
     self.assertEqual(Sub(Variable("X"), Variable("X")).variables(), [Variable("X")])
     self.assertEqual(Div(Variable("X"), Variable("X")).variables(), [Variable("X")])
     self.assertEqual(
         Or(
             Greater(Variable("X"), Number(42)), And(TRUE, Less(Variable("X"), Number(1)))
         ).variables(),
         [Variable("X")],
     )
예제 #11
0
def test_message_in_message() -> None:
    length = ModularInteger("Message_In_Message.Length", Pow(Number(2), Number(16)))

    length_value = Message(
        "Message_In_Message.Length_Value",
        [
            Link(INITIAL, Field("Length")),
            Link(Field("Length"), Field("Value"), length=Mul(Number(8), Variable("Length"))),
            Link(Field("Value"), FINAL),
        ],
        {Field("Length"): length, Field("Value"): Opaque()},
    )

    derived_length_value = DerivedMessage("Message_In_Message.Derived_Length_Value", length_value)

    message = Message(
        "Message_In_Message.Message",
        [
            Link(INITIAL, Field("Foo_Length")),
            Link(Field("Foo_Value"), Field("Bar_Length")),
            Link(Field("Bar_Value"), FINAL),
            Link(
                Field("Foo_Length"),
                Field("Foo_Value"),
                length=Mul(Variable("Foo_Length"), Number(8)),
            ),
            Link(
                Field("Bar_Length"),
                Field("Bar_Value"),
                length=Mul(Variable("Bar_Length"), Number(8)),
            ),
        ],
        {
            Field("Foo_Length"): length,
            Field("Foo_Value"): Opaque(),
            Field("Bar_Length"): length,
            Field("Bar_Value"): Opaque(),
        },
    )

    derived_message = DerivedMessage("Message_In_Message.Derived_Message", message)

    assert_messages_files(
        [f"{TESTDIR}/message_in_message.rflx"],
        [length_value, derived_length_value, message, derived_message],
    )
예제 #12
0
def test_tlv_message_with_not_operator_exhausting() -> None:
    message = Message(
        "TLV::Message_With_Not_Operator_Exhausting",
        [
            Link(INITIAL, Field("Tag")),
            Link(
                Field("Tag"),
                Field("Length"),
                Not(Not(Not(NotEqual(Variable("Tag"), Variable("Msg_Data"))))),
            ),
            Link(
                Field("Tag"),
                FINAL,
                reduce(
                    lambda acc, f: f(acc),
                    [Not, Not] * 16,
                    Not(
                        Or(
                            Not(
                                Not(
                                    Equal(Variable("Tag"),
                                          Variable("Msg_Data")))),
                            Not(Equal(Variable("Tag"), Variable("Msg_Error"))),
                        )),
                ),
            ),
            Link(Field("Length"),
                 Field("Value"),
                 size=Mul(Variable("Length"), Number(8))),
            Link(Field("Value"), FINAL),
        ],
        {
            Field("Tag"): TLV_TAG,
            Field("Length"): TLV_LENGTH,
            Field("Value"): OPAQUE
        },
    )

    with pytest.raises(
            FatalError,
            match=re.escape(
                "failed to simplify complex expression `not (not (not (not "
                "(not (not (not (not (not (not (not (not (not (not (not (not "
                "(not (not (not (not (not (not (not (not (not (not (not (not "
                "(not (not (not (not (not (not (not (Tag = TLV::Msg_Data))\n"
                "                                 "
                "or not (Tag = TLV::Msg_Error))))))))))))))))))))))))))))))))))` "
                "after `16` iterations, best effort: "
                "`not (not (not (not (not (not (not (not (not (not (not (not (not "
                "(not (not (not (not (Tag = TLV::Msg_Data\n"
                "                 or Tag /= TLV::Msg_Error)))))))))))))))))`"),
    ):
        model = PyRFLX(model=Model([TLV_TAG, TLV_LENGTH, message]))
        pkg = model.package("TLV")
        msg = pkg.new_message("Message_With_Not_Operator_Exhausting")
        test_bytes = b"\x01\x00\x04\x00\x00\x00\x00"
        msg.parse(test_bytes)
예제 #13
0
def test_valid_length_reference() -> None:
    structure = [
        Link(INITIAL, Field("F1")),
        Link(Field("F1"), Field("F2"), length=Mul(Number(8), Variable("F1"))),
        Link(Field("F2"), FINAL),
    ]
    types = {
        Field("F1"): MODULAR_INTEGER,
        Field("F2"): Opaque(),
    }
    Message("P.M", structure, types)
예제 #14
0
def test_ass_expr_substituted() -> None:
    assert_equal(
        And(Equal(Variable("X"), Number(1)), Variable("Y")).substituted(
            lambda x: Variable(f"P_{x}") if isinstance(x, Variable) else x
        ),
        And(Equal(Variable("P_X"), Number(1)), Variable("P_Y")),
    )
    assert_equal(
        Mul(Variable("X"), Number(1)).substituted(
            lambda x: Variable("Y") if x == Mul(Variable("X"), Number(1)) else x
        ),
        Variable("Y"),
    )
    assert_equal(
        And(Equal(Variable("X"), Number(1)), Variable("Y")).substituted(
            lambda x: Variable(f"P_{x}")
            if isinstance(x, Variable)
            else (Or(*x.terms) if isinstance(x, And) else x)
        ),
        Or(Equal(Variable("P_X"), Number(1)), Variable("P_Y")),
    )
예제 #15
0
def test_mathematical_expression_precedence() -> None:
    assert_equal(
        grammar.mathematical_expression().parseString("A - B * 2**3 - 1")[0],
        Sub(Sub(Variable("A"), Mul(Variable("B"), Pow(Number(2), Number(3)))), Number(1)),
    )
    assert_equal(
        grammar.mathematical_expression().parseString("(A - B) * 2**3 - 1")[0],
        Sub(Mul(Sub(Variable("A"), Variable("B")), Pow(Number(2), Number(3))), Number(1)),
    )
    assert_equal(
        grammar.mathematical_expression().parseString("A - B * 2**(3 - 1)")[0],
        Sub(Variable("A"), Mul(Variable("B"), Pow(Number(2), Sub(Number(3), Number(1))))),
    )
    assert_equal(
        grammar.mathematical_expression().parseString("A - (B * 2)**3 - 1")[0],
        Sub(Sub(Variable("A"), Pow(Mul(Variable("B"), Number(2)), Number(3))), Number(1)),
    )
    assert_equal(
        grammar.mathematical_expression().parseString("A - (B * 2**3 - 1)")[0],
        Sub(Variable("A"), Sub(Mul(Variable("B"), Pow(Number(2), Number(3))), Number(1))),
    )
예제 #16
0
파일: models.py 프로젝트: senier/RecordFlux
def create_array_inner_message() -> Message:
    length_type = ModularInteger("Arrays.Length", Pow(Number(2), Number(8)))

    structure = [
        Link(INITIAL, Field("Length")),
        Link(Field("Length"),
             Field("Payload"),
             length=Mul(Variable("Length"), Number(8))),
        Link(Field("Payload"), FINAL),
    ]

    types = {Field("Length"): length_type, Field("Payload"): Payload()}

    return Message("Arrays.Inner_Message", structure, types)
예제 #17
0
def test_opaque_valid_byte_aligned_dynamic_mul() -> None:
    Message(
        "P.M",
        [
            Link(INITIAL, Field("L")),
            Link(Field("L"), Field("O1"), length=Mul(Number(8),
                                                     Variable("L"))),
            Link(Field("O1"), FINAL),
        ],
        {
            Field("L"): MODULAR_INTEGER,
            Field("O1"): Opaque()
        },
    )
예제 #18
0
파일: models.py 프로젝트: senier/RecordFlux
def create_array_messages_message() -> Message:
    structure = [
        Link(INITIAL, Field("Length")),
        Link(Field("Length"),
             Field("Messages"),
             length=Mul(Variable("Length"), Number(8))),
        Link(Field("Messages"), FINAL),
    ]

    types = {
        Field("Length"):
        ModularInteger("Arrays.Length", Pow(Number(2), Number(8))),
        Field("Messages"):
        Array("Arrays.Inner_Messages", Reference("Arrays.Inner_Message")),
    }

    return Message("Arrays.Messages_Message", structure, types)
예제 #19
0
def test_invalid_negative_field_length_range_integer() -> None:
    o = Field(ID("O", location=Location((44, 3))))
    structure = [
        Link(INITIAL, Field("L")),
        Link(
            Field("L"),
            o,
            length=Mul(Number(8), Sub(Variable("L"), Number(50))),
        ),
        Link(o, FINAL),
    ]
    types = {Field("L"): RANGE_INTEGER, o: Opaque()}
    assert_message_model_error(
        structure,
        types,
        r'^<stdin>:44:3: model: error: negative length for field "O" [(]L -> O[)]$',
    )
예제 #20
0
def test_tlv_message_with_not_operator() -> None:
    message = Message(
        "TLV::Message_With_Not_Operator",
        [
            Link(INITIAL, Field("Tag")),
            Link(
                Field("Tag"),
                Field("Length"),
                Not(Not(Not(NotEqual(Variable("Tag"), Variable("Msg_Data"))))),
            ),
            Link(
                Field("Tag"),
                FINAL,
                Not(
                    Not(
                        Not(
                            Or(
                                Not(
                                    Not(
                                        Equal(Variable("Tag"),
                                              Variable("Msg_Data")))),
                                Not(
                                    Equal(Variable("Tag"),
                                          Variable("Msg_Error"))),
                            )))),
            ),
            Link(Field("Length"),
                 Field("Value"),
                 size=Mul(Variable("Length"), Number(8))),
            Link(Field("Value"), FINAL),
        ],
        {
            Field("Tag"): TLV_TAG,
            Field("Length"): TLV_LENGTH,
            Field("Value"): OPAQUE
        },
    )

    model = PyRFLX(model=Model([TLV_TAG, TLV_LENGTH, message]))
    pkg = model.package("TLV")
    msg = pkg.new_message("Message_With_Not_Operator")
    test_bytes = b"\x01\x00\x04\x00\x00\x00\x00"
    msg.parse(test_bytes)
    assert msg.valid_message
    assert msg.bytestring == test_bytes
예제 #21
0
def test_tlv_valid_enum() -> None:
    structure = [
        Link(INITIAL, Field("L")),
        Link(Field("L"), Field("T")),
        Link(
            Field("T"),
            Field("V"),
            length=Mul(Number(8), Variable("L")),
            condition=And(NotEqual(Variable("T"), Variable("TWO")),
                          LessEqual(Variable("L"), Number(8192))),
        ),
        Link(Field("V"), FINAL),
    ]
    types = {
        Field("L"): RANGE_INTEGER,
        Field("T"): ENUMERATION,
        Field("V"): Opaque(),
    }
    Message("P.M", structure, types)
예제 #22
0
def test_aggregate_equal_invalid_length_field() -> None:

    length = Field(ID("Length", Location((2, 5))))
    magic = Field(ID("Magic", Location((3, 5))))

    structure = [
        Link(INITIAL, length),
        Link(length,
             magic,
             length=Mul(Number(8),
                        Variable("Length"),
                        location=Location((6, 5)))),
        Link(
            magic,
            FINAL,
            condition=Equal(Variable("Magic"),
                            Aggregate(Number(1), Number(2)),
                            location=Location((10, 5))),
        ),
    ]
    types = {
        Field("Length"):
        RangeInteger("P.Length_Type", Number(10), Number(100), Number(8),
                     Location((5, 10))),
        Field(ID("Magic", Location((17, 3)))):
        Opaque(),
    }
    assert_message_model_error(
        structure,
        types,
        r"^"
        r'<stdin>:10:5: model: error: contradicting condition in "P.M"\n'
        r'<stdin>:2:5: model: info: on path: "Length"\n'
        r'<stdin>:3:5: model: info: on path: "Magic"\n'
        r'<stdin>:6:5: model: info: unsatisfied "Magic\'Length = 8 [*] Length"\n'
        r'<stdin>:10:5: model: info: unsatisfied "2 [*] 8 = Magic\'Length"\n'
        r'<stdin>:5:10: model: info: unsatisfied "Length >= 10"'
        r"$",
    )
예제 #23
0
def parse_mathematical_expression(string: str, location: int,
                                  tokens: list) -> MathExpr:
    result: List[MathExpr] = tokens[0]
    while len(result) > 1:
        left = result.pop(0)
        operator = result.pop(0)
        right = result.pop(0)
        expression: MathExpr
        if operator == '+':
            expression = Add(left, right)
        elif operator == '-':
            expression = Sub(left, right)
        elif operator == '*':
            expression = Mul(left, right)
        elif operator == '/':
            expression = Div(left, right)
        elif operator == '**':
            expression = Pow(left, right)
        else:
            raise ParseFatalException(string, location,
                                      'unexpected mathematical operator')
        result.insert(0, expression)
    return result[0]
예제 #24
0
def parse_mathematical_expression(string: str, location: int,
                                  tokens: ParseResults) -> Expr:
    result: List[Expr] = tokens[0]
    while len(result) > 1:
        left = result.pop(0)
        operator = result.pop(0)
        right = result.pop(0)
        expression: Expr
        if operator == "+":
            expression = Add(left, right)
        elif operator == "-":
            expression = Sub(left, right)
        elif operator == "*":
            expression = Mul(left, right)
        elif operator == "/":
            expression = Div(left, right)
        elif operator == "**":
            expression = Pow(left, right)
        else:
            raise ParseFatalException(string, location,
                                      "unexpected mathematical operator")
        result.insert(0, expression)
    return result[0]
예제 #25
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)
예제 #26
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)
예제 #27
0
)

NULL_MESSAGE = Message("Null::Message", [], {}, skip_proof=True)
NULL_MODEL = Model([NULL_MESSAGE])

TLV_TAG = Enumeration(
    "TLV::Tag", [("Msg_Data", Number(1)), ("Msg_Error", Number(3))], Number(8), always_valid=False
)
TLV_LENGTH = ModularInteger("TLV::Length", Pow(Number(2), Number(16)))
TLV_MESSAGE = Message(
    "TLV::Message",
    [
        Link(INITIAL, Field("Tag")),
        Link(Field("Tag"), Field("Length"), Equal(Variable("Tag"), Variable("Msg_Data"))),
        Link(Field("Tag"), FINAL, Equal(Variable("Tag"), Variable("Msg_Error"))),
        Link(Field("Length"), Field("Value"), size=Mul(Variable("Length"), Number(8))),
        Link(Field("Value"), FINAL),
    ],
    {Field("Tag"): TLV_TAG, Field("Length"): TLV_LENGTH, Field("Value"): OPAQUE},
    skip_proof=True,
)
TLV_MODEL = Model([TLV_TAG, TLV_LENGTH, TLV_MESSAGE])

TLV_MESSAGES = Sequence("TLV::Messages", TLV_MESSAGE)
TLV_TAGS = Sequence("TLV::Tags", TLV_TAG)

TLV_WITH_CHECKSUM_TAG = Enumeration(
    "TLV_With_Checksum::Tag",
    [("Msg_Data", Number(1)), ("Msg_Error", Number(3))],
    Number(8),
    always_valid=False,
예제 #28
0
def test_mul() -> None:
    assert Mul(Number(6), Number(4)).z3expr() == z3.IntVal(6) * z3.IntVal(4)
    assert_equal(
        Mul(Number(2), Number(4), Number(8)).z3expr(), z3.IntVal(2) * z3.IntVal(4) * z3.IntVal(8)
    )
예제 #29
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)
예제 #30
0
 def test_term_to_bytes(self) -> None:
     self.assertEqual(
         Add(Mul(Number(8), Number(48)), Sub(Value('X'), Number(80)),
             Div(Number(8), Number(24))).to_bytes(),
         Add(Mul(Number(1), Number(6)), Sub(Value('X'), Number(10)),
             Div(Number(1), Number(3))))