Diameter

The system provides a Python object alc.diameter, which is an instance of class alc.Diameter, to inspect and modify Diameter packets.

Note

Only the pre-provided alc.diameter object should be used in script, the class alc.Diameter should not be used directly.

The alc.Diameter class

Terminology

The methods on the alc.Diameter class use a set of data representations for handling the AVPs. The terminology and corresponding data types are as follows:

Attributes defined on Diameter messages

top-level-AVP

AVP appearing at the top level in a Diameter message,
not embedded in the Data field of a grouped AVP

embedded-AVP

AVP embedded in the Data field of a grouped AVP.
An embedded AVP can be a grouped AVP; this is called nesting.

AVP-tuple

(code, vendor, flags) tuple with types (int, int, bytes)

AVP-value-tuple

(flags, data) tuple with types (bytes, bytes)

AVP-key-tuple

(code, vendor) tuple with types (int, int)

grouped-AVP-value-tuple

(flags, grouped_avps) tuple with types (bytes, grouped-AVP-dictionnary)

grouped-AVP-dictionnary

dict of nested AVPs where:

  • keys are of type AVP-key-tuple

  • values are of type list[AVP-value-tuples] or list[grouped-AVP-value-tuples]

Instance Attributes

DIAMETER header fields are exposed as instance attributes on the object.

Attributes defined on Diameter messages

Attribute

Access

Type

version

rw

bytes

msg_length

ro

bytes

flags

rw

bytes

code

rw

bytes

application_id

rw

bytes

hop_by_hop_id

rw

bytes

end_to_end_id

rw

bytes

Methods

drop()

Drops the Diameter message. The packet is consumed at TCP level (ack send). A drop triggers retransmissions at the Diameter level.

get_avps_list()

Returns a list of AVP-tuples. Each AVP-tuple represents an instance of an AVP in the message.

  • Applies to top-level-AVPs only.

  • The position in the list corresponds with the position of the AVP in the message at that stage in the script.

  • When executed before any clear or set AVP method, the list order corresponds with the AVP order in the received message.

  • When multiple instances of an AVP are present in the message, multiple instances appear in the list.

  • The Vendor ID has value zero when not present.

  • Grouped AVPs cannot be distinguished from other AVPs in the list.

return

list of AVP-tuples

print(alc.diameter.get_avps_list())
#[(263, 0, b'@'), (264, 0, b'@'), (296, 0, b'@'), (258, 0, b'@'), (416, 0, b'@'), (415, 0, b'@'), (268, 0, b'@'), (55, 0, b'@'), (456, 0, b'@'), (456, 0, b'@'), (456, 0, b'@'), (293, 0, b'@'), (256, 12645, b'\x80')]
get_avps(code, vendor, /)

Returns a list of AVP-value-tuples. Each AVP-value-tuple represents an instance of the specified AVP in the message.

  • Applies to top-level-AVPs only.

  • The position in the list corresponds with the position of the AVP instance in the message at that stage in the script.

  • When executed before any clear or set AVP method, the list order corresponds with the AVP order in the received message.

  • If the specified AVP is a grouped AVP, the data contains all the embedded AVPs.

  • An empty list is returned if the specified AVP is not present.

  • The Vendor ID value zero matches top-level-AVPs without the Vendor ID field.

param int code

AVP code

param int vendor

AVP Vendor ID, the value zero matches AVPs without Vendor ID field

return

list of AVP-value-tuples

print(alc.diameter.get_avps(263, 0))
#[('@', 'bng.nokia.com;1398156449;28')]
set_avps(code, vendor, values, /)

Deletes existing top level AVPs of the specified code and vendor and inserts new AVPs vendor with the specified code, vendor and values. For each entry in the AVP-value-tuple list, a top-level-AVP instance is inserted.

  • If the specified Vendor ID value is zero, no Vendor ID field is inserted and setting the Vendor-Specific bit in the flags field of the AVP value tuple results in a Python error.

  • If the specified Vendor ID value is non-zero, a Vendor ID field is inserted. Not setting the Vendor-Specific bit in the flags field of the AVP value tuple results in a Python error.

  • Padding between AVPs, AVP length, and Diameter message length is adapted accordingly by the system.

param int code

AVP code

param int vendor

AVP Vendor ID, the value zero means not to insert a Vendor ID field

param values

list of AVP-value-tuples

alc.diameter.set_avps(461, 0, [(b'\x40', b'Python-1'), (b'\x40', b'Python-2')])
clear_avps(code, vendor, /)

Removes all instances of the specified AVP from the message.

  • Applies to top-level-AVPs only.

  • If the specified AVP is not present, no Python error is generated.

param int code

AVP code

param int vendor

AVP Vendor ID, the value zero matches AVPs without Vendor-Id field

d.clear_avps(256, 12645)
set_fixed_position_avps(avps, /)

Places the specified top-level-AVPs at the beginning of the message.

  • AVPs are ordered as specified in the avps tuple.

  • AVPs not present in the message but specified in avps are ignored.

  • AVPs present in the message and not specified in avps are included in the final message after the AVPs listed in the ordered AVPs tuple. The order is deterministic but implementation specific.

  • This method can appear at any point in the script. The last call overrides the previous one.

param list avps

tuple of AVP-key-tuples

Note

In Python 2, calling this function interferes with fetching AVPs in a subsequent get_avp_list() call. This restriction is no longer present in the Python 3 implementation.

alc.diameter.set_fixed_position_avps([(263,0), (264,0), (296,0), (268,0)])
get_grouped_avps(code, vendor, grouped_avps=(), /)

Returns a list of grouped-AVP-value-tuples with each grouped-AVP-dictionary entry representing an embedded AVP. Each grouped-AVP-value-tuple represents an instance of the specified AVP in the message.

  • Applies to top-level-AVPs of type grouped only.

  • The position in the list corresponds with the position of the grouped AVP instance in the message at that stage in the script. When executed before any clear or set AVP method, the list order corresponds with the AVP order in the received message.

  • The position of the embedded AVPs in the grouped-AVP-dictionary does not correspond with the position in the grouped AVP.

  • If the grouped_avps argument is empty, only the top-level-AVP specified by code and vendor arguments is expanded.

  • To expand nested AVPs (grouped AVPs embedded in a grouped AVP), they must be specified as a tuple in the grouped_avps argument.

param int code

AVP code

param int vendor

AVP Vendor Id

param tuple grouped_avps

tuple of AVP-key-tuples listing which embedded AVPs need to be expanded recursively

returns

list of grouped-AVP-value-tuples

raises ValueError

when the top-level-AVP or one of the AVPs in the grouped_avps cannot be decoded as a grouped-avp.

# To expand the Multiple Services Credit Control (456) grouped top level AVP:
print(alc.diameter.get_grouped_avps(456, 0))
#[(b'@', {(432, 0): [(b'@', b'\x00\x00\x00\x01')], (431, 0): [(b'@', b'\x00\x00\x01\xa4@\x00\x00\x0c\x00\x00\x00d')], (448, 0): [(b'@', b'\x00\x00\x04\xb0')], (268, 0): [(b'@', b'\x00\x00\x07\xd1')]}), (b'@', {(432, 0): [(b'@', b'\x00\x00\x00\x02')], (431, 0): [(b'@', b'\x00\x00\x01\xa4@\x00\x00\x0c\x00\x00\x03\x84')], (448, 0): [(b'@', b'\x00\x00\x04\xb0')], (268, 0): [(b'@', b'\x00\x00\x07\xd1')]}), (b'@', {(432, 0): [(b'@', b'\x00\x00\x00\x03')], (431, 0): [(b'@', b'\x00\x00\x01\xa4@\x00\x00\x0c\x00\x00\x00<')], (448, 0): [(b'@', b'\x00\x00\x04\xb0')], (268, 0): [(b'@', b'\x00\x00\x07\xd1')]})]

# To expand the nested Granted-Service-Unit AVP (code 431) in the grouped Multiple Services Credit Control top level AVP (code 456):
print(alc.diameter.get_grouped_avps(456, 0, ((456, 0), (431, 0))))
#[(b'@', {(432, 0): [(b'@', b'\x00\x00\x00\x01')], (431, 0): [(b'@', {(420, 0): [(b'@', b'\x00\x00\x00d')]})], (448, 0): [(b'@', b'\x00\x00\x04\xb0')], (268, 0): [(b'@', b'\x00\x00\x07\xd1')]}), (b'@', {(432, 0): [(b'@', b'\x00\x00\x00\x02')], (431, 0): [(b'@', {(420, 0): [(b'@', b'\x00\x00\x03\x84')]})], (448, 0): [(b'@', b'\x00\x00\x04\xb0')], (268, 0): [(b'@', b'\x00\x00\x07\xd1')]}), (b'@', {(432, 0): [(b'@', b'\x00\x00\x00\x03')], (431, 0): [(b'@', {(420, 0): [(b'@', b'\x00\x00\x00<')]})], (448, 0): [(b'@', b'\x00\x00\x04\xb0')], (268, 0): [(b'@', b'\x00\x00\x07\xd1')]})]
set_grouped_avps(code, vendor, grouped_avps, /)

Deletes existing grouped top level AVPs of the specified code and vendor and inserts new AVPs with the specified grouped_avps.

  • The order of the embedded-AVPs in the grouped AVP cannot be specified.

  • Padding between AVPs, AVP length, and Diameter message length is adjusted accordingly.

param int code

AVP code

param int vendor

AVP Vendor ID, the value zero means not to insert a Vendor ID field

param grouped_avps

list of grouped-AVP-value-tuples

alc.diameter.set_grouped_avps(456,0,[(b'@', {(432, 0): [(b'@', b'\x00\x00\x00\x01')], (431, 0): [(b'@', {(420, 0): [(b'@', b'\x00\x00\x00\x2b')]})], (448, 0): [(b'@', b'\x00\x00\x04\xb0')], (268, 0): [(b'@', b'\x00\x00\x07\xd1')]}), (b'@', {(432, 0): [(b'@', b'\x00\x00\x00\x03')], (431, 0): [(b'@', {(420, 0): [(b'@', b'\x00\x00\x00\x53')]})], (448, 0): [(b'@', b'\x00\x00\x04\xb0')], (268, 0): [(b'@', b'\x00\x00\x07\xd1')]})])