PFCP
The system provides a python object alc.pfcp
to inspect and modify the PFCP packets.
The alc.pfcp
object
Attributes
The object exposes the header fields as attributes on the object.
Attribute |
Description |
Access |
Type |
---|---|---|---|
flags |
Complete flags field as an 8-bit integer |
ro |
int |
version |
PFCP version |
ro |
int |
fo_flag |
FO flag (follow on) marking another PFCP message follows in the same UDP frame |
ro |
bool |
mp_flag |
Flag marking if there is a msg_priority field |
ro |
bool |
s_flag |
Flag marking if there is a SEID field |
ro |
bool |
msg_type |
Message type |
ro |
int |
msg_len |
Message length |
ro |
int |
seid |
Session Endpoint Identifier; None if the header field is not present |
ro |
int|None |
seq_number |
Sequence number |
ro |
int |
msg_priority |
Message priority; None if the header field is not present |
ro |
int|None |
Methods
- alc.Pfcp.drop()
Drops the packet.
- alc.Pfcp.get_ie_list()
Returns a list of IE-types that are present in the packet.
The order of the elements is the same as they appear in the packet.
If there are multiple instances of the same IE, the IE-type appears multiple times in the tuple.
- Return type
list
- alc.Pfcp.has(type, /)
Returns if an IE of the specified type is present at the top-level.
- Parameters
type (int) – IE-type to find
- Return type
bool
- alc.Pfcp.get(type, /)
Returns all values of the IEs with the specified type. The values are returned as the exact bytestrings as they appear in the packet.
If the specified type does not exist, the result is an empty tuple: ()
If a specific instance has zero length or no values, the corresponding bytestring is an empty bytestring: b””
- Parameters
type (int) – IE-type to fetch
- Return type
tuple of bytestrings
- alc.Pfcp.set(type, value, /)
Replaces the currently present IEs of the specific type with new ones. Multiple values can be specified in a tuple in which case one IE with the specified type is added for each item in the tuple.
- Parameters
type (int) – IE-type to set
value (bytes|tuple(bytes)) – value of the IE; length is computed from this value
- alc.Pfcp.clear(type, /)
Removes all IEs with the specified type.
- Parameters
type (int) – IE-type to clear
Constants
Name |
Value |
---|---|
MSG_TYPE_HEARTBEAT_REQ |
1 |
MSG_TYPE_HEARTBEAT_RESP |
2 |
MSG_TYPE_PFD_MGMT_REQ |
3 |
MSG_TYPE_PFD_MGMT_RESP |
4 |
MSG_TYPE_ASSOC_SETUP_REQ |
5 |
MSG_TYPE_ASSOC_SETUP_RESP |
6 |
MSG_TYPE_ASSOC_UPDATE_REQ |
7 |
MSG_TYPE_ASSOC_UPDATE_RESP |
8 |
MSG_TYPE_ASSOC_RELEASE_REQ |
9 |
MSG_TYPE_ASSOC_RELEASE_RESP |
10 |
MSG_TYPE_VERSION_NOT_SUP_RESP |
11 |
MSG_TYPE_NODE_REPORT_REQ |
12 |
MSG_TYPE_NODE_REPORT_RESP |
13 |
MSG_TYPE_SESSION_SET_DEL_REQ |
14 |
MSG_TYPE_SESSION_SET_DEL_RESP |
15 |
MSG_TYPE_SESSION_EST_REQ |
50 |
MSG_TYPE_SESSION_EST_RESP |
51 |
MSG_TYPE_SESSION_MOD_REQ |
52 |
MSG_TYPE_SESSION_MOD_RESP |
53 |
MSG_TYPE_SESSION_DEL_REQ |
54 |
MSG_TYPE_SESSION_DEL_RESP |
55 |
MSG_TYPE_SESSION_REPORT_REQ |
56 |
MSG_TYPE_SESSION_REPORT_RESP |
57 |
The alc.pfcp_utils
module
Decoded IE classes
The module comes with a list of pre-defined classes which represent a decoded IE. These classes known how to convert between a bytes-representation of a specific IE and a Python-object of that class that allows direct interaction with its value.
AbstractIE
BasicIE
IntegerIE
StringIE
GroupedIE
Other decoders can be created by subclassing the AbstractIE
class, providing a sensible __init__ function and overriding the following two methods:
AbstractIE.encode()
AbstractIE.from_bytes()
Decoding
The module provides a function to decode a bytes representation of the value of an IE.
This function can be passed in the result of a call to alc.pfcp.get()
as the value for the iter_of_bytes argument.
Examples
Example 1: Adding and removing IEs
from alc import pfcp
from pfcp_utils import IntegerIE, GroupedIE, BasicIE, StringIE
# remove some IEs from the packet
pfcp.clear(17)
pfcp.clear(2)
# create new IEs and insert them
new_ies = [
IntegerIE(109, 4, 1),
BasicIE(25, b'\x00'),
GroupedIE(7, [qerid_ie, corrid_ie, gatestatus_ie])
]
for ie in new_ies:
pfcp.set(ie.type, ie.encode())
# add multiple IEs of the same type
pfcp.set(22, (StringIE(22, "ISP1").encode(), StringIE(22, "ISP2").encode()))
Example 2: Fetching and decoding IEs
from alc import pfcp
from pfcp_utils import IntegerIE, decode_ies
# fetch some IEs
# result will be a tuple of bytestrings
raw_qer_ies = pfcp.get(109)
# decode them using an IntegerIE decoder
qer_ies = decode_ies(109, raw_qer_ies, IntegerIE)
Example 3: Working with grouped IEs
from alc import pfcp
from pfcp_utils import IntegerIE, GroupedIE, BasicIE, StringIE, decode_ies
# Fetch a grouped IE and iterate its sub-IEs
create_pdrs = decode_ies(1, pfcp.get(1), GroupedIE)
for pdr in create_pdrs:
for ie in pdr.sub_ies:
print(ie)
# You can pass in extra info about sub-IEs that you want to be decoded automatically
# Notice that you can specify sub-IEs to be GroupedIE as well, which will cause the
# decoding to recurse even further.
sub_decoders = {2: GroupedIE, 20: IntegerIE}
create_pdrs = decode_ies(1, pfcp.get(1), GroupedIE, sub_decoders = sub_decoders)
# Find a specific sub-ie
for pdr in create_pdrs:
for pdi_ie in pdr.sub_ies_of_type(2):
print(ie)
# Find and modify specific sub-sub-ie:
for pdr in create_pdrs:
for pdi_ie in pdr.sub_ies_of_type(2):
for src_iface_ie in pdi_ie.sub_ies_of_type(20):
src_iface = src_iface_ie.value & 0x0f
if src_iface == 1:
src_iface = 2
# create a groupedIE
qerid_ie = IntegerIE(109, 4, 1)
corrid_ie = IntegerIE(28, 4, corrid)
gatestatus_ie = BasicIE(25, b'\x00')
qer_ie = GroupedIE(7, [qerid_ie, corrid_ie, gatestatus_ie])
# Add a sub-IE to an existing grouped IE:
for pdr in create_pdrs:
pdr.sub_ies.append(qerid_ie)
# In order to propagate these changes into the pfcp-packet, the outer
# GroupedIE needs to be encoded again and the resulting bytes has to be
# set on the packet.
alc.pfcp.set(1, tuple(ie.encode() for ie in create_pdrs))