Ejemplo n.º 1
0
 def test_message_field_condition(self) -> None:
     self.assertEqual(ETHERNET_FRAME.field_condition(INITIAL), TRUE)
     self.assertEqual(
         ETHERNET_FRAME.field_condition(Field("TPID")),
         Equal(Variable("Type_Length_TPID"), Number(33024, 16)),
     )
     self.assertEqual(
         ETHERNET_FRAME.field_condition(Field("Type_Length")),
         Or(
             NotEqual(Variable("Type_Length_TPID"), Number(33024, 16)),
             Equal(Variable("Type_Length_TPID"), Number(33024, 16)),
         ),
     )
     self.assertEqual(
         ETHERNET_FRAME.field_condition(Field("Payload")),
         Or(
             And(
                 Or(
                     NotEqual(Variable("Type_Length_TPID"), Number(33024, 16)),
                     Equal(Variable("Type_Length_TPID"), Number(33024, 16)),
                 ),
                 LessEqual(Variable("Type_Length"), Number(1500)),
             ),
             And(
                 Or(
                     NotEqual(Variable("Type_Length_TPID"), Number(33024, 16)),
                     Equal(Variable("Type_Length_TPID"), Number(33024, 16)),
                 ),
                 GreaterEqual(Variable("Type_Length"), Number(1536)),
             ),
         ),
     )
Ejemplo n.º 2
0
def test_aggregate_equal_array_invalid_length() -> None:
    magic = Field(ID("Magic", Location((3, 5))))
    structure = [
        Link(INITIAL, magic, length=Number(40, location=Location((19, 17)))),
        Link(
            magic,
            FINAL,
            condition=NotEqual(Variable("Magic"),
                               Aggregate(Number(1), Number(2)),
                               Location((17, 3))),
        ),
    ]
    types = {
        Field("Magic"):
        Array(
            "P.Arr",
            ModularInteger("P.Modular",
                           Number(128),
                           location=Location((66, 3)))),
    }
    assert_message_model_error(
        structure,
        types,
        r"^"
        r'<stdin>:17:3: model: error: contradicting condition in "P.M"\n'
        r'<stdin>:3:5: model: info: on path: "Magic"\n'
        r'<stdin>:17:3: model: info: unsatisfied "2 [*] Modular\'Length = Magic\'Length"\n'
        r'<stdin>:66:3: model: info: unsatisfied "Modular\'Length = 7"\n'
        r'<stdin>:19:17: model: info: unsatisfied "Magic\'Length = 40"',
    )
Ejemplo n.º 3
0
 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)),
                 ),
             )
         ],
     )
Ejemplo n.º 4
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)
Ejemplo n.º 5
0
def parse_relation(string: str, location: int, tokens: list) -> Relation:
    if tokens[1] == '<':
        return Less(tokens[0], tokens[2])
    if tokens[1] == '<=':
        return LessEqual(tokens[0], tokens[2])
    if tokens[1] == '=':
        return Equal(tokens[0], tokens[2])
    if tokens[1] == '>=':
        return GreaterEqual(tokens[0], tokens[2])
    if tokens[1] == '>':
        return Greater(tokens[0], tokens[2])
    if tokens[1] == '/=':
        return NotEqual(tokens[0], tokens[2])
    raise ParseFatalException(string, location, 'unexpected relation operator')
Ejemplo n.º 6
0
def test_aggregate_equal_array_valid_length() -> None:
    structure = [
        Link(INITIAL, Field("Magic"), length=Number(14)),
        Link(
            Field("Magic"),
            FINAL,
            condition=NotEqual(Variable("Magic"),
                               Aggregate(Number(1), Number(2))),
        ),
    ]
    types = {
        Field("Magic"): Array("P.Arr", ModularInteger("P.Modular",
                                                      Number(128))),
    }
    Message("P.M", structure, types)
Ejemplo n.º 7
0
def parse_relation(string: str, location: int,
                   tokens: ParseResults) -> Relation:
    if tokens[1] == "<":
        return Less(tokens[0], tokens[2])
    if tokens[1] == "<=":
        return LessEqual(tokens[0], tokens[2])
    if tokens[1] == "=":
        return Equal(tokens[0], tokens[2])
    if tokens[1] == ">=":
        return GreaterEqual(tokens[0], tokens[2])
    if tokens[1] == ">":
        return Greater(tokens[0], tokens[2])
    if tokens[1] == "/=":
        return NotEqual(tokens[0], tokens[2])
    raise ParseFatalException(string, location, "unexpected relation operator")
Ejemplo n.º 8
0
def test_aggregate_inequal_valid_length() -> None:
    structure = [
        Link(INITIAL, Field("Magic"), length=Number(40)),
        Link(
            Field("Magic"),
            FINAL,
            condition=NotEqual(
                Variable("Magic"),
                Aggregate(Number(1), Number(2), Number(3), Number(4),
                          Number(4)),
            ),
        ),
    ]
    types = {
        Field("Magic"): Opaque(),
    }
    Message("P.M", structure, types)
Ejemplo n.º 9
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
Ejemplo n.º 10
0
def parse_relation(string: str, location: int,
                   tokens: ParseResults) -> Relation:
    def locn() -> Location:
        return Location(tokens[0].location.start, tokens[0].location.source,
                        tokens[2].location.end)

    if tokens[1] == "<":
        return Less(tokens[0], tokens[2], locn())
    if tokens[1] == "<=":
        return LessEqual(tokens[0], tokens[2], locn())
    if tokens[1] == "=":
        return Equal(tokens[0], tokens[2], locn())
    if tokens[1] == ">=":
        return GreaterEqual(tokens[0], tokens[2], locn())
    if tokens[1] == ">":
        return Greater(tokens[0], tokens[2], locn())
    if tokens[1] == "/=":
        return NotEqual(tokens[0], tokens[2], locn())
    raise ParseFatalException(string, location, "unexpected relation operator")
Ejemplo n.º 11
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)
Ejemplo n.º 12
0
def test_bin_expr_substituted() -> None:
    assert_equal(
        Less(Variable("X"), Number(1)).substituted(
            lambda x: Variable(f"P_{x}") if isinstance(x, Variable) else x
        ),
        Less(Variable("P_X"), Number(1)),
    )
    assert_equal(
        Sub(Variable("X"), Number(1)).substituted(
            lambda x: Variable("Y") if x == Sub(Variable("X"), Number(1)) else x
        ),
        Variable("Y"),
    )
    assert_equal(
        NotEqual(Variable("X"), Number(1)).substituted(
            lambda x: Variable(f"P_{x}")
            if isinstance(x, Variable)
            else (Equal(x.left, x.right) if isinstance(x, NotEqual) else x)
        ),
        Equal(Variable("P_X"), Number(1)),
    )
Ejemplo n.º 13
0
def test_aggregate_inequal_invalid_length() -> None:
    structure = [
        Link(INITIAL, Field("Magic"), length=Number(40)),
        Link(
            Field("Magic"),
            FINAL,
            condition=NotEqual(Variable("Magic"),
                               Aggregate(Number(1), Number(2))),
        ),
    ]
    types = {
        Field("Magic"): Opaque(),
    }
    assert_message_model_error(
        structure,
        types,
        r"^"
        r'model: error: contradicting condition in "P.M"\n'
        r'model: info: on path: "Magic"\n'
        r'model: info: unsatisfied "2 [*] 8 = Magic\'Length"\n'
        r'model: info: unsatisfied "Magic\'Length = 40"',
    )
Ejemplo n.º 14
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)
Ejemplo n.º 15
0
    def context_predicate(self, message: Message, composite_fields: Sequence[Field]) -> Expr:
        def valid_predecessors_invariant() -> Expr:
            return AndThen(
                *[
                    If(
                        [
                            (
                                Call(
                                    "Structural_Valid", [Indexed("Cursors", Name(f.affixed_name))]
                                ),
                                Or(
                                    *[
                                        AndThen(
                                            Call(
                                                "Structural_Valid"
                                                if l.source in composite_fields
                                                else "Valid",
                                                [Indexed("Cursors", Name(l.source.affixed_name))],
                                            ),
                                            Equal(
                                                Selected(
                                                    Indexed("Cursors", Name(f.affixed_name)),
                                                    "Predecessor",
                                                ),
                                                Name(l.source.affixed_name),
                                            ),
                                            l.condition,
                                        ).simplified(self.substitution(message, False))
                                        for l in message.incoming(f)
                                    ]
                                ),
                            )
                        ]
                    )
                    for f in message.fields
                    if f not in message.direct_successors(INITIAL)
                ]
            )

        def invalid_successors_invariant() -> Expr:
            return AndThen(
                *[
                    If(
                        [
                            (
                                AndThen(
                                    *[
                                        Call("Invalid", [Indexed("Cursors", Name(p.affixed_name))])
                                        for p in message.direct_predecessors(f)
                                    ]
                                ),
                                Call("Invalid", [Indexed("Cursors", Name(f.affixed_name))]),
                            )
                        ]
                    )
                    for f in message.fields
                    if f not in message.direct_successors(INITIAL)
                ]
            )

        return AndThen(
            If(
                [
                    (
                        NotEqual(Name(Name("Buffer")), NULL),
                        And(
                            Equal(First(Name("Buffer")), Name(Name("Buffer_First"))),
                            Equal(Last(Name("Buffer")), Name(Name("Buffer_Last"))),
                        ),
                    )
                ]
            ),
            GreaterEqual(
                Call(self.types.byte_index, [Name(Name("First"))]), Name(Name("Buffer_First"))
            ),
            LessEqual(Call(self.types.byte_index, [Name(Name("Last"))]), Name(Name("Buffer_Last"))),
            LessEqual(Name(Name("First")), Name(Name("Last"))),
            LessEqual(Name(Name("Last")), Div(Last(self.types.bit_index), Number(2))),
            ForAllIn(
                "F",
                ValueRange(First("Field"), Last("Field")),
                If(
                    [
                        (
                            Call("Structural_Valid", [Indexed(Name("Cursors"), Name("F"))]),
                            And(
                                GreaterEqual(
                                    Selected(Indexed(Name("Cursors"), Name("F")), "First"),
                                    Name(Name("First")),
                                ),
                                LessEqual(
                                    Selected(Indexed(Name("Cursors"), Name("F")), "Last"),
                                    Name(Name("Last")),
                                ),
                                LessEqual(
                                    Selected(Indexed(Name("Cursors"), Name("F")), "First"),
                                    Add(
                                        Selected(Indexed(Name("Cursors"), Name("F")), "Last"),
                                        Number(1),
                                    ),
                                ),
                                Equal(
                                    Selected(
                                        Selected(Indexed(Name("Cursors"), Name("F")), "Value"),
                                        "Fld",
                                    ),
                                    Name("F"),
                                ),
                            ),
                        )
                    ]
                ),
            ),
            valid_predecessors_invariant(),
            invalid_successors_invariant(),
            self.message_structure_invariant(message, prefix=False),
        )
Ejemplo n.º 16
0
ETHERNET_FRAME = Message(
    "Ethernet::Frame",
    [
        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)),
        ),
Ejemplo n.º 17
0
ETHERNET_FRAME = Message(
    "Ethernet.Frame",
    [
        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")),
Ejemplo n.º 18
0
def test_not_equal() -> None:
    assert NotEqual(Number(100), Number(1)).z3expr() == (z3.IntVal(100) != z3.IntVal(1))
Ejemplo n.º 19
0
 def test_not_equal_simplified(self) -> None:
     self.assertEqual(
         NotEqual(Value('X'), Add(Number(21), Number(21))).simplified(),
         NotEqual(Value('X'), Number(42)))
Ejemplo n.º 20
0
def test_not_equal_simplified() -> None:
    assert NotEqual(Number(0), Number(1)).simplified() == TRUE
    assert NotEqual(Number(1), Number(1)).simplified() == FALSE
    assert NotEqual(Number(2), Number(1)).simplified() == TRUE
Ejemplo n.º 21
0
 def test_not_equal_simplified(self) -> None:
     self.assertEqual(
         NotEqual(Variable("X"), Add(Number(21), Number(21))).simplified(),
         NotEqual(Variable("X"), Number(42)),
     )
Ejemplo n.º 22
0
 def test_not_equal_neg(self) -> None:
     self.assertEqual(-NotEqual(Variable("X"), Number(1)), Equal(Variable("X"), Number(1)))
Ejemplo n.º 23
0
 def test_not_equal(self) -> None:
     self.assertEqual(
         NotEqual(Number(100), Number(1)).z3expr(),
         z3.IntVal(100) != z3.IntVal(1))
Ejemplo n.º 24
0
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)
Ejemplo n.º 25
0
    def create_internal_functions(
        self, message: Message, composite_fields: Sequence[Field]
    ) -> UnitPart:
        def result(field: Field, message: Message) -> NamedAggregate:
            aggregate: List[Tuple[str, Expr]] = [("Fld", Name(field.affixed_name))]
            if field in message.fields and isinstance(message.types[field], Scalar):
                aggregate.append(
                    (
                        f"{field.name}_Value",
                        Call(
                            "Extract",
                            [
                                Slice("Ctx.Buffer.all", Name("Buffer_First"), Name("Buffer_Last")),
                                Name("Offset"),
                            ],
                        ),
                    )
                )
            return NamedAggregate(*aggregate)

        return UnitPart(
            [],
            [
                ExpressionFunctionDeclaration(
                    FunctionSpecification(
                        "Sufficient_Buffer_Length",
                        "Boolean",
                        [Parameter(["Ctx"], "Context"), Parameter(["Fld"], "Field")],
                    ),
                    And(
                        NotEqual(Name("Ctx.Buffer"), NULL),
                        LessEqual(Name("Ctx.First"), Div(Last(self.types.bit_index), Number(2))),
                        LessEqual(
                            Call("Field_First", [Name("Ctx"), Name("Fld")]),
                            Div(Last(self.types.bit_index), Number(2)),
                        ),
                        GreaterEqual(Call("Field_Length", [Name("Ctx"), Name("Fld")]), Number(0)),
                        LessEqual(
                            Call("Field_Length", [Name("Ctx"), Name("Fld")]),
                            Div(Last(self.types.bit_length), Number(2)),
                        ),
                        LessEqual(
                            Add(
                                Call("Field_First", [Name("Ctx"), Name("Fld")]),
                                Call("Field_Length", [Name("Ctx"), Name("Fld")]),
                            ),
                            Div(Last(self.types.bit_length), Number(2)),
                        ),
                        LessEqual(
                            Name("Ctx.First"), Call("Field_First", [Name("Ctx"), Name("Fld")])
                        ),
                        GreaterEqual(
                            Name("Ctx.Last"), Call("Field_Last", [Name("Ctx"), Name("Fld")])
                        ),
                    ),
                    [
                        Precondition(
                            And(
                                Call("Has_Buffer", [Name("Ctx")]),
                                Call("Valid_Next", [Name("Ctx"), Name("Fld")]),
                            )
                        )
                    ],
                ),
                ExpressionFunctionDeclaration(
                    FunctionSpecification(
                        "Composite_Field", "Boolean", [Parameter(["Fld"], "Field")]
                    ),
                    Case(
                        Name("Fld"),
                        [
                            (Name(f.affixed_name), TRUE if f in composite_fields else FALSE)
                            for f in message.fields
                        ],
                    ),
                ),
                SubprogramBody(
                    FunctionSpecification(
                        "Get_Field_Value",
                        "Field_Dependent_Value",
                        [Parameter(["Ctx"], "Context"), Parameter(["Fld"], "Field")],
                    ),
                    [
                        *self.common.field_bit_location_declarations(Name("Fld")),
                        *self.common.field_byte_location_declarations(),
                    ],
                    [
                        ReturnStatement(
                            Case(
                                Name("Fld"),
                                [
                                    (Name(f.affixed_name), result(f, message))
                                    for f in message.fields
                                ],
                            )
                        )
                    ],
                    [
                        Precondition(
                            AndThen(
                                Call("Has_Buffer", [Name("Ctx")]),
                                Call("Valid_Next", [Name("Ctx"), Name("Fld")]),
                                Call("Sufficient_Buffer_Length", [Name("Ctx"), Name("Fld")]),
                            )
                        ),
                        Postcondition(
                            Equal(Selected(Result("Get_Field_Value"), "Fld"), Name("Fld"))
                        ),
                    ],
                ),
            ],
        )
Ejemplo n.º 26
0
def test_not_equal_neg() -> None:
    assert -NotEqual(Variable("X"), Number(1)) == Equal(Variable("X"), Number(1))
Ejemplo n.º 27
0
def context_predicate(message: Message, composite_fields: Sequence[Field], prefix: str) -> Expr:
    def valid_predecessors_invariant() -> Expr:
        return AndThen(
            *[
                If(
                    [
                        (
                            Call(
                                "Structural_Valid",
                                [Indexed(Variable("Cursors"), Variable(f.affixed_name))],
                            ),
                            Or(
                                *[
                                    AndThen(
                                        Call(
                                            "Structural_Valid"
                                            if l.source in composite_fields
                                            else "Valid",
                                            [
                                                Indexed(
                                                    Variable("Cursors"),
                                                    Variable(l.source.affixed_name),
                                                )
                                            ],
                                        ),
                                        Equal(
                                            Selected(
                                                Indexed(
                                                    Variable("Cursors"), Variable(f.affixed_name),
                                                ),
                                                "Predecessor",
                                            ),
                                            Variable(l.source.affixed_name),
                                        ),
                                        l.condition.substituted(
                                            substitution(message, embedded=True)
                                        ),
                                    ).simplified()
                                    for l in message.incoming(f)
                                ]
                            ),
                        )
                    ]
                )
                for f in message.fields
                if f not in message.direct_successors(INITIAL)
            ]
        )

    def invalid_successors_invariant() -> Expr:
        return AndThen(
            *[
                If(
                    [
                        (
                            AndThen(
                                *[
                                    Call(
                                        "Invalid",
                                        [Indexed(Variable("Cursors"), Variable(p.affixed_name))],
                                    )
                                    for p in message.direct_predecessors(f)
                                ]
                            ),
                            Call(
                                "Invalid", [Indexed(Variable("Cursors"), Variable(f.affixed_name))],
                            ),
                        )
                    ]
                )
                for f in message.fields
                if f not in message.direct_successors(INITIAL)
            ]
        )

    return AndThen(
        If(
            [
                (
                    NotEqual(Variable("Buffer"), Variable("null")),
                    And(
                        Equal(First("Buffer"), Variable("Buffer_First")),
                        Equal(Last("Buffer"), Variable("Buffer_Last")),
                    ),
                )
            ]
        ),
        public_context_predicate(),
        ForAllIn(
            "F",
            ValueRange(First("Field"), Last("Field")),
            If(
                [
                    (
                        Call("Structural_Valid", [Indexed(Variable("Cursors"), Variable("F"))]),
                        And(
                            GreaterEqual(
                                Selected(Indexed(Variable("Cursors"), Variable("F")), "First"),
                                Variable("First"),
                            ),
                            LessEqual(
                                Selected(Indexed(Variable("Cursors"), Variable("F")), "Last"),
                                Variable("Last"),
                            ),
                            LessEqual(
                                Selected(Indexed(Variable("Cursors"), Variable("F")), "First"),
                                Add(
                                    Selected(Indexed(Variable("Cursors"), Variable("F")), "Last"),
                                    Number(1),
                                ),
                            ),
                            Equal(
                                Selected(
                                    Selected(Indexed(Variable("Cursors"), Variable("F")), "Value"),
                                    "Fld",
                                ),
                                Variable("F"),
                            ),
                        ),
                    )
                ]
            ),
        ),
        valid_predecessors_invariant(),
        invalid_successors_invariant(),
        message_structure_invariant(message, prefix, embedded=True),
    )
Ejemplo n.º 28
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)
Ejemplo n.º 29
0
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)