Message
API reference for diameter.message
.
Diameter base message implementation.
This module contains the base functions for encoding and decoding diameter message headers and messages.
Message ¶
Message(header: MessageHeader = None, avps: list[Avp] = None)
Base message class.
All implemented diameter commands extend this class.
The base message class is not intended to be used directly; its main purpose is to provide the Message.from_bytes class method, for parsing network-received bytes into Python diameter command message instances.
header
instance-attribute
¶
header: MessageHeader = header or MessageHeader()
A message header. Always exists, defaults to an empty header for new messages.
Note
The length
property of the message header is zero for newly
created messages and will not be set until the message is rendered
using the as_bytes method.
name
class-attribute
instance-attribute
¶
name: str = 'Unknown'
A human-readable diameter command code name, e.g. "Accounting-Request".
as_bytes ¶
as_bytes() -> bytes
Retrieve entire message as bytes.
Retrieving the message also builds each AVP it contains. Until this
point, the list of AVPs has not been built yet and the message header
length is still zero. The header length is updated every time
as_bytes()
is called.
find_avps ¶
Find specific AVPs in the message internal AVP tree.
If more than one code_and_vendor
pair is given, the list is assumed
to be a chain of AVPs to follow. The returned list of AVPs will be the
AVPs found at the end of each chain.
Examples:
In an AVP structure such as:
Multiple-Services-Credit-Control <Code: 0x1c8, Flags: 0x40 (-M-), Length: 168>
Requested-Service-Unit <Code: 0x1b5, Flags: 0x40 (-M-), Length: 0>
Used-Service-Unit <Code: 0x1be, Flags: 0x40 (-M-), Length: 84>
CC-Time <Code: 0x1a4, Flags: 0x40 (-M-), Length: 12, Val: 9>
CC-Total-Octets <Code: 0x1a5, Flags: 0x40 (-M-), Length: 16, Val: 0>
The "CC-Total-Octets" AVP can be found with:
>>> msg = Message()
>>> avp = msg.find_avps(
>>> (AVP_MULTIPLE_SERVICES_CREDIT_CONTROL, 0),
>>> (AVP_USED_SERVICE_UNIT, 0),
>>> (AVP_CC_TOTAL_OCTETS, 0))
>>> print(avp[0])
CC-Total-Octets <Code: 0x1a5, Flags: 0x40 (-M-), Length: 16, Val: 0>
The search is cached internally, repeating the same find operation will return a cached result.
Note
Searching for AVPs can be somewhat resource intensive, especially for larger command structures. For messages constructed from received network bytes, it is much cheaper to simply access the values of the message attributes directly. E.g. the example above is the same as:
>>> avp = msg.multiple_services_credit_control[0].used_service_unit[0].cc_total_octets
>>> print(avp[0])
0
The method can also be used to search any arbitrary AVP list, by passing
an optional keyword argument alt_avps
.
from_bytes
classmethod
¶
from_bytes(
msg_data: bytes, plain_msg: bool = False
) -> _AnyMessageType
Generate a new Message from network received bytes.
Accepts a byte string containing received network data and constructs a
new Message
instance, returning one of its subclasses, if the command
code is a known one.
If possible, the returned insance is one of the specific subclasses,
e.g. CreditControlRequest
or CapabilitiesExchangeRequest
, which
attempt to be as smart as possible and offer direct access to AVPs as
class attributes, i.e. CreditControlRequest.session_id
. If this is
not wanted, the additional keyword argument plain_msg
can be set to
True, which returns just an instance of Message
that holds the list
of parsed AVPs and does nothing else.
>>> # construct a specific Message with parsed attributes
>>> ccr = Message.from_bytes(b"...")
>>> ccr.session_id
labocs1.gy;379;3434872354
>>> # construct a plain message with no attribute access
>>> msg = Message.from_bytes(b"...", plain_msg=True)
>>> # does not work
>>> msg.session_id
AttributeError: 'CreditControl' object has no attribute 'session_id'
>>> # this will work
>>> session_id = msg.find_avps((AVP_SESSION_ID, 0))[0]
>>> session_id.value
labocs1.gy;379;3434872354
to_answer ¶
to_answer() -> _AnyMessageType
Produce answer from a request.
Copies the request message header to a new answer message, clearing all the flags except the proxyable bit. Attempts to by determine if a suitable python Answer class exists, if not, uses the base class and returns a new instance with the copied header.
type_factory
classmethod
¶
type_factory(header: MessageHeader) -> Type[_AnyMessageType] | None
Generate a type that should be used to create new instances.
This method is called internally by Message.from_bytes and it can be overridden by inheriting classes to indicate the specific type of message class to generate, e.g. in order to produce different types for "Request" and "Answer" messages, based on the given header.
If no type is returned, the base class type will be used.
MessageHeader ¶
MessageHeader(
version: int = 1,
length: int = 0,
command_flags: int = 0,
command_code: int = 0,
application_id: int = 0,
hop_by_hop_identifier: int = 0,
end_to_end_identifier: int = 0,
)
DefinedMessage ¶
DefinedMessage(header: MessageHeader = None, avps: list[Avp] = None)
Bases: Message
A base class for every diameter message that is defined in Python.
Every subclass of this class has AVPs defined as python instance attributes, defined based on the corresponding diameter specification.
The attribute values can be changed. When a DefinedMessage
instance is
converted back to bytes, appropriate AVPs are generated based on the set
instance attributes.
avps
property
writable
¶
avps: list[Avp]
Full list of all AVPs within the message.
If the message was generated from network-received bytes, the list of AVPs may not be in the same order as originally received. The returned list of AVPs contains first the AVPs defined by the base rfc6733 spec, if set, followed by any unknown AVPs.
UndefinedMessage ¶
UndefinedMessage(
header: MessageHeader = None, avps: list[Avp] = None
)
Bases: Message
A base class for every unknown command message.
Every diameter command message that does not map to an instance of
DefinedMessage
will be represented as an instance of UndefinedMessage
.
This class will automatically attempt to convert received AVPs into read-only instance attributes, using a naive conversion based on the AVP's name. The AVP name is converted into lower case and all "-" are replaced with underscores. I.e. a "Visited-PLMN-Id" AVP would be converted to a "visited_plmn_id" instance attribute.
If an AVP appears multiple times in the original message, it is converted into a list of AVPs.
If an AVP is of the type Grouped, it is converted into an instance of
UndefinedGroupedAvp
and its sub-AVPs are set as instance attributes as
well.
Note
Unlike DefinedMessage
, instances of this class cannot be converted
back to bytes; there is no conversion of set instance attributes into
actual AVPs. Instances of this class are effectively read-only.
dump ¶
dump(msg: Message) -> str
Produce a human-readable representation of the given message.
Produces a recursive text dump of the given message, its header and all AVPs that it contains. Will work also on unknown AVPs and message command codes; data that is not known to the diameter package is marked with "Unknown".
Is essentially the same as calling str
on the message itself, and then
recursively looping through each AVP and calling str(avp)
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
msg
|
Message
|
Any message type |
required |
Sample output:
Credit-Control <Version: 0x01, Length: 312, Flags: 0x40 (proxyable), Hop-by-Hop Identifier: 0x2711, End-to-End Identifier: 0x4e21>
Session-Id <Code: 0x107, Flags: 0x40 (-M-), Length: 73, Val: sctp-saegwc-poz01.lte.orange.pl;221424325;287370797;65574b0c-2d02>
Result-Code <Code: 0x10c, Flags: 0x40 (-M-), Length: 12, Val: 2001>
Origin-Host <Code: 0x108, Flags: 0x00 (---), Length: 21, Val: b'ocs6.mvno.net'>
Origin-Realm <Code: 0x128, Flags: 0x00 (---), Length: 16, Val: b'mvno.net'>
Auth-Application-Id <Code: 0x102, Flags: 0x40 (-M-), Length: 12, Val: 4>
CC-Request-Type <Code: 0x1a0, Flags: 0x40 (-M-), Length: 12, Val: 2>
CC-Request-Number <Code: 0x19f, Flags: 0x40 (-M-), Length: 12, Val: 952>
Multiple-Services-Credit-Control <Code: 0x1c8, Flags: 0x40 (-M-), Length: 128>
Granted-Service-Unit <Code: 0x1af, Flags: 0x40 (-M-), Length: 24>
CC-Total-Octets <Code: 0x1a5, Flags: 0x40 (-M-), Length: 16, Val: 174076000>
Rating-Group <Code: 0x1b0, Flags: 0x40 (-M-), Length: 12, Val: 8000>
Validity-Time <Code: 0x1c0, Flags: 0x40 (-M-), Length: 12, Val: 3600>
Result-Code <Code: 0x10c, Flags: 0x40 (-M-), Length: 12, Val: 2001>
Final-Unit-Indication <Code: 0x1ae, Flags: 0x40 (-M-), Length: 44>
Final-Unit-Action <Code: 0x1c1, Flags: 0x40 (-M-), Length: 12, Val: 0>
Unknown <Code: 0x266e, Flags: 0x80 (V--), Length: 21, Vnd: None, Val: b'TERMINATE'>
Quota-Holding-Time <Code: 0x367, Flags: 0xc0 (VM-), Length: 16, Vnd: TGPP, Val: 0>
Note that:
- Message header version, flags and identifiers are as hexadecimal strings
- AVP flags are shown as three letters, "VMP", where "V" indicates vendor specific, "M" indicates mandatory and "P" indicates private. If a flag is not set, it is replaced by a "-"
- AVP codes are in hexadecimal
- Unknown AVPs are rendered, but shown as "Unknown"