[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
If eg. PCRF or AAA diameter link is not yet ready (eg. PCRF crashed), and
a client sends a CreateSessionRequest announcing its ow F-TEID,
then open5gs-smfd answers with Create Session Response Cause=
"Remote peer not responding", but it is not setting the received F-TEID
in the header of the response, instead it sends with TEI=0.
As a result, the peer cannot match the CreateSessionResponse, and needs
to rely on its own timeout timer to figure out that specific request failed.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
# Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
2019-04-27 14:54:30 +00:00
|
|
|
|
|
|
|
# This file is part of Open5GS.
|
|
|
|
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU Affero General Public License as published by
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
2017-03-14 02:24:15 +00:00
|
|
|
#
|
2019-04-27 14:54:30 +00:00
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
2017-03-14 02:24:15 +00:00
|
|
|
#
|
2019-04-27 14:54:30 +00:00
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
2017-03-14 02:24:15 +00:00
|
|
|
from docx import Document
|
2021-10-27 06:26:57 +00:00
|
|
|
from docx.document import Document as _Document
|
|
|
|
from docx.oxml.text.paragraph import CT_P
|
|
|
|
from docx.oxml.table import CT_Tbl
|
|
|
|
from docx.table import _Cell, Table
|
|
|
|
from docx.text.paragraph import Paragraph
|
|
|
|
|
2017-03-14 02:24:15 +00:00
|
|
|
import re, os, sys, string
|
2017-03-14 08:09:27 +00:00
|
|
|
import datetime
|
2017-03-14 02:24:15 +00:00
|
|
|
import getopt
|
2017-03-14 08:09:27 +00:00
|
|
|
import getpass
|
2017-03-14 02:24:15 +00:00
|
|
|
|
|
|
|
version = "0.1.0"
|
|
|
|
|
2017-03-15 04:39:57 +00:00
|
|
|
msg_list = {}
|
|
|
|
type_list = {}
|
|
|
|
group_list = {}
|
|
|
|
|
2017-03-14 02:24:15 +00:00
|
|
|
verbosity = 0
|
|
|
|
filename = ""
|
|
|
|
outdir = './'
|
|
|
|
cachedir = './cache/'
|
|
|
|
|
|
|
|
FAIL = '\033[91m'
|
|
|
|
INFO = '\033[93m'
|
|
|
|
ENDC = '\033[0m'
|
|
|
|
|
2017-03-14 13:44:48 +00:00
|
|
|
def d_print(string):
|
2017-03-14 02:24:15 +00:00
|
|
|
if verbosity > 0:
|
2017-03-15 02:54:08 +00:00
|
|
|
sys.stdout.write(string)
|
2017-03-14 02:24:15 +00:00
|
|
|
|
2017-03-14 13:44:48 +00:00
|
|
|
def d_info(string):
|
2017-03-15 02:54:08 +00:00
|
|
|
sys.stdout.write(INFO + string + ENDC + "\n")
|
2017-03-14 02:24:15 +00:00
|
|
|
|
2017-03-14 13:44:48 +00:00
|
|
|
def d_error(string):
|
2017-03-14 02:24:15 +00:00
|
|
|
sys.stderr.write(FAIL + string + ENDC + "\n")
|
|
|
|
sys.exit(0)
|
|
|
|
|
2017-03-15 02:54:08 +00:00
|
|
|
def write_file(f, string):
|
|
|
|
f.write(string)
|
|
|
|
d_print(string)
|
|
|
|
|
2017-03-14 13:44:48 +00:00
|
|
|
def output_header_to_file(f):
|
2017-03-14 08:09:27 +00:00
|
|
|
now = datetime.datetime.now()
|
|
|
|
f.write("""/*
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
If eg. PCRF or AAA diameter link is not yet ready (eg. PCRF crashed), and
a client sends a CreateSessionRequest announcing its ow F-TEID,
then open5gs-smfd answers with Create Session Response Cause=
"Remote peer not responding", but it is not setting the received F-TEID
in the header of the response, instead it sends with TEI=0.
As a result, the peer cannot match the CreateSessionResponse, and needs
to rely on its own timeout timer to figure out that specific request failed.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
2019-04-27 14:54:30 +00:00
|
|
|
*
|
|
|
|
* This file is part of Open5GS.
|
2017-03-14 08:09:27 +00:00
|
|
|
*
|
2019-04-27 14:54:30 +00:00
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
2017-03-14 08:09:27 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
""")
|
|
|
|
f.write("/*******************************************************************************\n")
|
2019-06-11 09:28:25 +00:00
|
|
|
f.write(" * This file had been created by gtp-tlv.py script v%s\n" % (version))
|
2017-03-14 08:09:27 +00:00
|
|
|
f.write(" * Please do not modify this file but regenerate it via script.\n")
|
|
|
|
f.write(" * Created on: %s by %s\n * from %s\n" % (str(now), getpass.getuser(), filename))
|
|
|
|
f.write(" ******************************************************************************/\n\n")
|
2017-03-14 02:24:15 +00:00
|
|
|
|
|
|
|
def usage():
|
2021-06-21 13:36:38 +00:00
|
|
|
print("Python generating TLV build/parser for GTPv2-C v%s" % (version))
|
|
|
|
print("Usage: python gtp-tlv.py [options]")
|
|
|
|
print("Available options:")
|
|
|
|
print("-d Enable script debug")
|
|
|
|
print("-f [file] Input file to parse")
|
|
|
|
print("-o [dir] Output files to given directory")
|
|
|
|
print("-c [dir] Cache files to given directory")
|
|
|
|
print("-h Print this help and return")
|
2017-03-14 02:24:15 +00:00
|
|
|
|
2017-03-14 08:09:27 +00:00
|
|
|
def v_upper(v):
|
2017-03-15 07:07:52 +00:00
|
|
|
return re.sub('3GPP', '', re.sub('\'', '_', re.sub('/', '_', re.sub('-', '_', re.sub(' ', '_', v)))).upper())
|
2017-03-14 13:44:48 +00:00
|
|
|
|
2017-03-14 08:09:27 +00:00
|
|
|
def v_lower(v):
|
2017-03-15 07:07:52 +00:00
|
|
|
return re.sub('3gpp', '', re.sub('\'', '_', re.sub('/', '_', re.sub('-', '_', re.sub(' ', '_', v)))).lower())
|
2017-03-14 08:09:27 +00:00
|
|
|
|
2017-03-14 13:44:48 +00:00
|
|
|
def get_cells(cells):
|
2021-06-21 13:36:38 +00:00
|
|
|
instance = cells[4].text
|
2017-03-14 13:44:48 +00:00
|
|
|
if instance.isdigit() is not True:
|
|
|
|
return None
|
2021-06-21 13:36:38 +00:00
|
|
|
ie_type = re.sub('\s*$', '', re.sub('\s*\n*\s*\([A-z]*\s*NOTE.*\)*', '', cells[3].text))
|
2017-03-14 13:44:48 +00:00
|
|
|
if ie_type.find('LDN') != -1:
|
|
|
|
ie_type = 'LDN'
|
|
|
|
elif ie_type.find('APCO') != -1:
|
|
|
|
ie_type = 'APCO'
|
2017-03-14 14:56:12 +00:00
|
|
|
elif ie_type.find('Charging Id') != -1:
|
|
|
|
ie_type = 'Charging ID'
|
2017-03-31 00:06:07 +00:00
|
|
|
elif ie_type.find('H(e)NB Information Reporting') != -1:
|
|
|
|
ie_type = 'eNB Information Reporting'
|
|
|
|
elif ie_type.find('IPv4 Configuration Parameters (IP4CP)') != -1:
|
|
|
|
ie_type = 'IP4CP'
|
2020-07-01 04:22:55 +00:00
|
|
|
elif ie_type.find('Charging characteristics') != -1:
|
|
|
|
ie_type = 'Charging Characteristics'
|
|
|
|
elif ie_type.find('Change To Report Flags') != -1:
|
|
|
|
ie_type = 'Change to Report Flags'
|
|
|
|
elif ie_type.find('APN RATE Control Status') != -1:
|
|
|
|
ie_type = 'APN Rate Control Status'
|
2017-03-14 13:44:48 +00:00
|
|
|
if ie_type not in type_list.keys():
|
|
|
|
assert False, "Unknown IE type : [" \
|
|
|
|
+ cells[3].text + "]" + "(" + ie_type + ")"
|
2021-06-21 13:36:38 +00:00
|
|
|
presence = cells[1].text
|
2020-07-01 04:22:55 +00:00
|
|
|
presence = re.sub('\n', '', presence);
|
2021-06-21 13:36:38 +00:00
|
|
|
ie_value = re.sub('\s*\n*\s*\([^\)]*\)*', '', cells[0].text)
|
2022-06-11 14:51:00 +00:00
|
|
|
ie_value = re.sub('\n', '', ie_value);
|
2021-06-21 13:36:38 +00:00
|
|
|
comment = cells[2].text.encode('ascii', 'ignore').decode('utf-8')
|
2017-03-14 13:44:48 +00:00
|
|
|
comment = re.sub('\n|\"|\'|\\\\', '', comment);
|
2017-03-15 04:39:57 +00:00
|
|
|
|
2017-03-15 06:49:56 +00:00
|
|
|
if int(instance) > int(type_list[ie_type]["max_instance"]):
|
2017-03-15 04:39:57 +00:00
|
|
|
type_list[ie_type]["max_instance"] = instance
|
|
|
|
write_file(f, "type_list[\"" + ie_type + "\"][\"max_instance\"] = \"" + instance + "\"\n")
|
|
|
|
|
2017-03-14 13:44:48 +00:00
|
|
|
return { "ie_type" : ie_type, "ie_value" : ie_value, "presence" : presence, "instance" : instance, "comment" : comment }
|
|
|
|
|
|
|
|
def write_cells_to_file(name, cells):
|
|
|
|
write_file(f, name + ".append({ \"ie_type\" : \"" + cells["ie_type"] + \
|
|
|
|
"\", \"ie_value\" : \"" + cells["ie_value"] + \
|
|
|
|
"\", \"presence\" : \"" + cells["presence"] + \
|
|
|
|
"\", \"instance\" : \"" + cells["instance"] + \
|
2017-03-15 02:54:08 +00:00
|
|
|
"\", \"comment\" : \"" + cells["comment"] + "\"})\n")
|
2017-03-14 13:44:48 +00:00
|
|
|
|
2021-10-27 06:26:57 +00:00
|
|
|
def document_paragraph_tables(document):
|
|
|
|
|
|
|
|
tables = []
|
|
|
|
# iterate .docx objects
|
|
|
|
def iter_block_items(parent):
|
|
|
|
|
|
|
|
if isinstance(parent, _Document):
|
|
|
|
parent_elm = parent.element.body
|
|
|
|
elif isinstance(parent, _Cell):
|
|
|
|
parent_elm = parent._tc
|
|
|
|
elif isinstance(parent, _Row):
|
|
|
|
parent_elm = parent._tr
|
|
|
|
else:
|
|
|
|
raise ValueError("Document format error.")
|
|
|
|
|
|
|
|
for child in parent_elm.iterchildren():
|
|
|
|
if isinstance(child, CT_P):
|
|
|
|
yield Paragraph(child, parent)
|
|
|
|
elif isinstance(child, CT_Tbl):
|
|
|
|
yield Table(child, parent)
|
|
|
|
|
|
|
|
idx = -1
|
|
|
|
paragraph = ''
|
|
|
|
for block in iter_block_items(document):
|
|
|
|
table=[]
|
|
|
|
# memoize the paragraph
|
|
|
|
if isinstance(block, Paragraph):
|
|
|
|
paragraph = block.text
|
|
|
|
continue
|
|
|
|
# fetch the table
|
|
|
|
if isinstance(block, Table):
|
|
|
|
idx += 1
|
|
|
|
table = block
|
|
|
|
# store table having a paragraph name
|
|
|
|
tables.append([idx, paragraph, table])
|
|
|
|
|
|
|
|
return tables
|
|
|
|
|
|
|
|
|
2017-03-14 02:24:15 +00:00
|
|
|
try:
|
|
|
|
opts, args = getopt.getopt(sys.argv[1:], "df:ho:c:", ["debug", "file", "help", "output", "cache"])
|
|
|
|
except getopt.GetoptError as err:
|
|
|
|
# print help information and exit:
|
|
|
|
usage()
|
|
|
|
sys.exit(2)
|
|
|
|
|
|
|
|
for o, a in opts:
|
|
|
|
if o in ("-d", "--debug"):
|
|
|
|
verbosity = 1
|
|
|
|
if o in ("-f", "--file"):
|
|
|
|
filename = a
|
|
|
|
if o in ("-o", "--output"):
|
|
|
|
outdir = a
|
|
|
|
if outdir.rfind('/') != len(outdir):
|
|
|
|
outdir += '/'
|
|
|
|
if o in ("-c", "--cache"):
|
2021-10-23 23:37:11 +00:00
|
|
|
cachedir = a
|
2017-03-14 02:24:15 +00:00
|
|
|
if cachedir.rfind('/') != len(cachedir):
|
|
|
|
cachedir += '/'
|
|
|
|
if o in ("-h", "--help"):
|
|
|
|
usage()
|
|
|
|
sys.exit(2)
|
|
|
|
|
|
|
|
if os.path.isfile(filename) and os.access(filename, os.R_OK):
|
2021-06-21 13:36:38 +00:00
|
|
|
file = open(filename, 'r')
|
2017-03-14 02:24:15 +00:00
|
|
|
else:
|
2017-03-14 13:44:48 +00:00
|
|
|
d_error("Cannot find file : " + filename)
|
2017-03-14 02:24:15 +00:00
|
|
|
|
2017-03-14 13:44:48 +00:00
|
|
|
d_info("[Message List]")
|
2019-07-06 13:52:09 +00:00
|
|
|
cachefile = cachedir + 'tlv-msg-list.py'
|
2017-03-14 02:24:15 +00:00
|
|
|
if os.path.isfile(cachefile) and os.access(cachefile, os.R_OK):
|
2021-06-21 13:36:38 +00:00
|
|
|
exec(open(cachefile).read())
|
|
|
|
print("Read from " + cachefile)
|
2017-03-14 02:24:15 +00:00
|
|
|
else:
|
2017-03-14 04:50:13 +00:00
|
|
|
document = Document(filename)
|
2022-04-29 12:28:16 +00:00
|
|
|
f = open(cachefile, 'w')
|
2017-03-14 02:24:15 +00:00
|
|
|
|
|
|
|
msg_table = ""
|
2021-10-27 06:26:57 +00:00
|
|
|
for i, paragraph, table in document_paragraph_tables(document):
|
2017-03-14 02:24:15 +00:00
|
|
|
cell = table.rows[0].cells[0]
|
|
|
|
if cell.text.find('Message Type value') != -1:
|
|
|
|
msg_table = table
|
2021-10-27 06:26:57 +00:00
|
|
|
d_print("Table Index = %d Name = [%s]\n" % (i, paragraph))
|
|
|
|
write_file(f, "# [%s] Index = %d\n" % (paragraph, i))
|
2017-03-14 02:24:15 +00:00
|
|
|
|
|
|
|
for row in msg_table.rows[2:-4]:
|
2021-06-21 13:36:38 +00:00
|
|
|
key = row.cells[1].text
|
|
|
|
type = row.cells[0].text
|
2017-03-14 02:24:15 +00:00
|
|
|
if type.isdigit() is False:
|
|
|
|
continue
|
|
|
|
if int(type) in range(128, 160):
|
|
|
|
continue
|
|
|
|
if int(type) in range(231, 240):
|
|
|
|
continue
|
|
|
|
if key.find('Reserved') != -1:
|
|
|
|
continue
|
|
|
|
key = re.sub('\s*\n*\s*\([^\)]*\)*', '', key)
|
2022-06-11 14:51:00 +00:00
|
|
|
key = re.sub('\n', '', key);
|
2017-03-14 02:24:15 +00:00
|
|
|
msg_list[key] = { "type": type }
|
2017-03-15 02:54:08 +00:00
|
|
|
write_file(f, "msg_list[\"" + key + "\"] = { \"type\" : \"" + type + "\" }\n")
|
2017-03-14 02:24:15 +00:00
|
|
|
f.close()
|
|
|
|
|
2017-03-14 13:44:48 +00:00
|
|
|
d_info("[IE Type List]")
|
2019-12-07 04:17:00 +00:00
|
|
|
cachefile = cachedir + 'tlv-type-list.py'
|
2017-03-14 02:24:15 +00:00
|
|
|
if os.path.isfile(cachefile) and os.access(cachefile, os.R_OK):
|
2021-06-21 13:36:38 +00:00
|
|
|
exec(open(cachefile).read())
|
|
|
|
print("Read from " + cachefile)
|
2017-03-14 02:24:15 +00:00
|
|
|
else:
|
2017-03-14 04:50:13 +00:00
|
|
|
document = Document(filename)
|
2022-04-29 12:28:16 +00:00
|
|
|
f = open(cachefile, 'w')
|
2017-03-14 02:24:15 +00:00
|
|
|
|
|
|
|
ie_table = ""
|
2021-10-27 06:26:57 +00:00
|
|
|
for i, paragraph, table in document_paragraph_tables(document):
|
2017-03-14 02:24:15 +00:00
|
|
|
cell = table.rows[0].cells[0]
|
|
|
|
if cell.text.find('IE Type value') != -1:
|
|
|
|
ie_table = table
|
2021-10-27 06:26:57 +00:00
|
|
|
d_print("Table Index = %d Name = [%s]\n" % (i, paragraph))
|
|
|
|
write_file(f, "# [%s] Index = %d\n" % (paragraph, i))
|
2017-03-14 02:24:15 +00:00
|
|
|
|
|
|
|
for row in ie_table.rows[1:-5]:
|
2021-06-21 13:36:38 +00:00
|
|
|
key = row.cells[1].text
|
2022-06-11 14:51:00 +00:00
|
|
|
type = row.cells[0].text
|
|
|
|
if type.isdigit() is False:
|
|
|
|
continue
|
2017-03-14 02:24:15 +00:00
|
|
|
if key.find('Reserved') != -1:
|
|
|
|
continue
|
|
|
|
if key.find('MM Context') != -1:
|
|
|
|
continue
|
|
|
|
elif key.find('Recovery') != -1:
|
|
|
|
key = 'Recovery'
|
|
|
|
elif key.find('Trusted WLAN Mode Indication') != -1:
|
|
|
|
key = 'TWMI'
|
|
|
|
elif key.find('LDN') != -1:
|
|
|
|
key = 'LDN'
|
|
|
|
elif key.find('APCO') != -1:
|
|
|
|
key = 'APCO'
|
2017-03-14 04:50:13 +00:00
|
|
|
elif key.find('Remote UE IP information') != -1:
|
|
|
|
key = 'Remote UE IP Information'
|
2017-07-25 01:11:05 +00:00
|
|
|
elif key.find('Procedure Transaction ID') != -1:
|
|
|
|
key = 'PTI'
|
2017-03-14 02:24:15 +00:00
|
|
|
else:
|
2021-06-21 13:36:38 +00:00
|
|
|
key = re.sub('.*\(', '', row.cells[1].text)
|
2017-03-14 02:24:15 +00:00
|
|
|
key = re.sub('\)', '', key)
|
2017-03-14 08:09:27 +00:00
|
|
|
key = re.sub('\s*$', '', key)
|
2022-06-11 14:51:00 +00:00
|
|
|
|
2017-03-15 04:39:57 +00:00
|
|
|
type_list[key] = { "type": type , "max_instance" : "0" }
|
|
|
|
write_file(f, "type_list[\"" + key + "\"] = { \"type\" : \"" + type)
|
|
|
|
write_file(f, "\", \"max_instance\" : \"0\" }\n")
|
2017-03-14 02:24:15 +00:00
|
|
|
f.close()
|
2017-03-15 04:39:57 +00:00
|
|
|
type_list['MM Context'] = { "type": "107", "max_instance" : "0" }
|
2017-03-14 02:24:15 +00:00
|
|
|
|
2017-03-14 14:56:12 +00:00
|
|
|
d_info("[Group IE List]")
|
2019-07-06 13:52:09 +00:00
|
|
|
cachefile = cachedir + 'tlv-group-list.py'
|
2017-03-14 14:56:12 +00:00
|
|
|
if os.path.isfile(cachefile) and os.access(cachefile, os.R_OK):
|
2021-06-21 13:36:38 +00:00
|
|
|
exec(open(cachefile).read())
|
|
|
|
print("Read from " + cachefile)
|
2017-03-14 14:56:12 +00:00
|
|
|
else:
|
|
|
|
document = Document(filename)
|
2022-04-29 12:28:16 +00:00
|
|
|
f = open(cachefile, 'w')
|
2017-03-14 14:56:12 +00:00
|
|
|
|
2021-10-27 06:26:57 +00:00
|
|
|
for i, paragraph, table in document_paragraph_tables(document):
|
2017-03-14 14:56:12 +00:00
|
|
|
if table.rows[0].cells[0].text.find('Octet') != -1 and \
|
|
|
|
table.rows[0].cells[2].text.find('IE Type') != -1:
|
2017-03-15 02:54:08 +00:00
|
|
|
d_print("Table Index = %d\n" % i)
|
2017-03-14 14:56:12 +00:00
|
|
|
|
|
|
|
row = table.rows[0];
|
|
|
|
|
|
|
|
if len(re.findall('\d+', row.cells[2].text)) == 0:
|
|
|
|
continue;
|
2021-06-21 13:36:38 +00:00
|
|
|
ie_type = re.findall('\d+', row.cells[2].text)[0]
|
|
|
|
ie_name = re.sub('\s*IE Type.*', '', row.cells[2].text)
|
2017-03-14 14:56:12 +00:00
|
|
|
|
2021-10-27 06:26:57 +00:00
|
|
|
write_file(f, "# [%s] Index = %d\n" % (paragraph, i))
|
|
|
|
|
2017-03-14 14:56:12 +00:00
|
|
|
if ie_name not in group_list.keys():
|
2017-03-15 07:26:29 +00:00
|
|
|
ies = []
|
|
|
|
write_file(f, "ies = []\n")
|
2017-03-14 14:56:12 +00:00
|
|
|
for row in table.rows[4:]:
|
|
|
|
cells = get_cells(row.cells)
|
|
|
|
if cells is None:
|
|
|
|
continue
|
|
|
|
|
2017-03-15 07:26:29 +00:00
|
|
|
ies_is_added = True
|
|
|
|
for ie in ies:
|
2017-03-15 01:53:33 +00:00
|
|
|
if (cells["ie_type"], cells["instance"]) == (ie["ie_type"], ie["instance"]):
|
2017-03-15 07:26:29 +00:00
|
|
|
ies_is_added = False
|
|
|
|
if ies_is_added is True:
|
|
|
|
ies.append(cells)
|
|
|
|
write_cells_to_file("ies", cells)
|
2017-03-15 01:53:33 +00:00
|
|
|
|
2020-07-01 04:22:55 +00:00
|
|
|
ie_idx = str(int(ie_type)+100)
|
|
|
|
group_list[ie_name] = { "index" : ie_idx, "type" : ie_type, "ies" : ies }
|
|
|
|
write_file(f, "group_list[\"" + ie_name + "\"] = { \"index\" : \"" + ie_idx + "\", \"type\" : \"" + ie_type + "\", \"ies\" : ies }\n")
|
2017-03-14 14:56:12 +00:00
|
|
|
else:
|
2017-03-15 01:53:33 +00:00
|
|
|
group_list_is_added = False
|
2017-03-15 07:26:29 +00:00
|
|
|
added_ies = group_list[ie_name]["ies"]
|
|
|
|
write_file(f, "added_ies = group_list[\"" + ie_name + "\"][\"ies\"]\n")
|
2017-03-14 14:56:12 +00:00
|
|
|
for row in table.rows[4:]:
|
|
|
|
cells = get_cells(row.cells)
|
|
|
|
if cells is None:
|
|
|
|
continue
|
2017-03-15 01:53:33 +00:00
|
|
|
|
2017-03-15 07:26:29 +00:00
|
|
|
ies_is_added = True
|
|
|
|
for ie in group_list[ie_name]["ies"]:
|
2017-03-14 14:56:12 +00:00
|
|
|
if (cells["ie_type"], cells["instance"]) == (ie["ie_type"], ie["instance"]):
|
2017-03-15 07:26:29 +00:00
|
|
|
ies_is_added = False
|
|
|
|
for ie in ies:
|
2017-03-14 14:56:12 +00:00
|
|
|
if (cells["ie_type"], cells["instance"]) == (ie["ie_type"], ie["instance"]):
|
2017-03-15 07:26:29 +00:00
|
|
|
ies_is_added = False
|
|
|
|
if ies_is_added is True:
|
|
|
|
added_ies.append(cells)
|
|
|
|
write_cells_to_file("added_ies", cells)
|
2017-03-15 01:53:33 +00:00
|
|
|
group_list_is_added = True
|
|
|
|
if group_list_is_added is True:
|
2020-07-01 04:22:55 +00:00
|
|
|
ie_idx = str(int(ie_type)+100)
|
|
|
|
group_list[ie_name] = { "index" : ie_idx, "type" : ie_type, "ies" : added_ies }
|
|
|
|
write_file(f, "group_list[\"" + ie_name + "\"] = { \"index\" : \"" + ie_idx + "\", \"type\" : \"" + ie_type + "\", \"ies\" : added_ies }\n")
|
2017-03-14 14:56:12 +00:00
|
|
|
f.close()
|
|
|
|
|
2020-07-01 04:22:55 +00:00
|
|
|
msg_list["Echo Request"]["table"] = 8
|
|
|
|
msg_list["Echo Response"]["table"] = 9
|
|
|
|
msg_list["Create Session Request"]["table"] = 10
|
|
|
|
msg_list["Create Session Response"]["table"] = 15
|
2023-03-05 03:37:14 +00:00
|
|
|
msg_list["Create Bearer Request"]["table"] = 21
|
|
|
|
msg_list["Create Bearer Response"]["table"] = 26
|
|
|
|
msg_list["Bearer Resource Command"]["table"] = 29
|
|
|
|
msg_list["Bearer Resource Failure Indication"]["table"] = 31
|
|
|
|
msg_list["Modify Bearer Request"]["table"] = 33
|
|
|
|
msg_list["Modify Bearer Response"]["table"] = 37
|
|
|
|
msg_list["Delete Session Request"]["table"] = 43
|
|
|
|
msg_list["Delete Bearer Request"]["table"] = 45
|
|
|
|
msg_list["Delete Session Response"]["table"] = 50
|
|
|
|
msg_list["Delete Bearer Response"]["table"] = 53
|
|
|
|
msg_list["Downlink Data Notification"]["table"] = 56
|
|
|
|
msg_list["Downlink Data Notification Acknowledge"]["table"] = 59
|
|
|
|
msg_list["Downlink Data Notification Failure Indication"]["table"] = 60
|
|
|
|
msg_list["Delete Indirect Data Forwarding Tunnel Request"]["table"] = 61
|
|
|
|
msg_list["Delete Indirect Data Forwarding Tunnel Response"]["table"] = 62
|
|
|
|
msg_list["Modify Bearer Command"]["table"] = 63
|
|
|
|
msg_list["Modify Bearer Failure Indication"]["table"] = 66
|
|
|
|
msg_list["Update Bearer Request"]["table"] = 68
|
|
|
|
msg_list["Update Bearer Response"]["table"] = 73
|
|
|
|
msg_list["Delete Bearer Command"]["table"] = 76
|
|
|
|
msg_list["Delete Bearer Failure Indication"]["table"] = 79
|
|
|
|
msg_list["Create Indirect Data Forwarding Tunnel Request"]["table"] = 82
|
|
|
|
msg_list["Create Indirect Data Forwarding Tunnel Response"]["table"] = 84
|
|
|
|
msg_list["Release Access Bearers Request"]["table"] = 86
|
|
|
|
msg_list["Release Access Bearers Response"]["table"] = 87
|
|
|
|
msg_list["Modify Access Bearers Request"]["table"] = 91
|
|
|
|
msg_list["Modify Access Bearers Response"]["table"] = 94
|
2017-03-14 02:24:15 +00:00
|
|
|
|
|
|
|
for key in msg_list.keys():
|
|
|
|
if "table" in msg_list[key].keys():
|
2017-03-14 13:44:48 +00:00
|
|
|
d_info("[" + key + "]")
|
2019-07-06 13:52:09 +00:00
|
|
|
cachefile = cachedir + "tlv-msg-" + msg_list[key]["type"] + ".py"
|
2017-03-14 02:24:15 +00:00
|
|
|
if os.path.isfile(cachefile) and os.access(cachefile, os.R_OK):
|
2021-06-21 13:36:38 +00:00
|
|
|
exec(open(cachefile).read())
|
|
|
|
print("Read from " + cachefile)
|
2017-03-14 02:24:15 +00:00
|
|
|
else:
|
2017-03-14 04:50:13 +00:00
|
|
|
document = Document(filename)
|
2022-04-29 12:28:16 +00:00
|
|
|
f = open(cachefile, 'w')
|
2017-03-14 02:24:15 +00:00
|
|
|
|
2017-03-15 07:07:52 +00:00
|
|
|
ies = []
|
|
|
|
write_file(f, "ies = []\n")
|
2017-03-14 04:50:13 +00:00
|
|
|
table = document.tables[msg_list[key]["table"]]
|
2017-03-14 02:24:15 +00:00
|
|
|
for row in table.rows[1:]:
|
2017-03-14 13:44:48 +00:00
|
|
|
cells = get_cells(row.cells)
|
|
|
|
if cells is None:
|
2017-03-14 02:24:15 +00:00
|
|
|
continue
|
2017-03-14 14:56:12 +00:00
|
|
|
|
2017-03-15 01:53:33 +00:00
|
|
|
ies_is_added = True
|
2017-03-14 14:56:12 +00:00
|
|
|
for ie in ies:
|
|
|
|
if (cells["ie_type"], cells["instance"]) == (ie["ie_type"], ie["instance"]):
|
2017-03-15 01:53:33 +00:00
|
|
|
ies_is_added = False
|
|
|
|
if ies_is_added is True:
|
2017-03-14 14:56:12 +00:00
|
|
|
ies.append(cells)
|
|
|
|
write_cells_to_file("ies", cells)
|
2017-03-14 04:50:13 +00:00
|
|
|
msg_list[key]["ies"] = ies
|
2017-03-15 02:54:08 +00:00
|
|
|
write_file(f, "msg_list[key][\"ies\"] = ies\n")
|
2017-03-14 02:24:15 +00:00
|
|
|
f.close()
|
2017-03-14 08:09:27 +00:00
|
|
|
|
2017-03-15 13:28:04 +00:00
|
|
|
type_list["Recovery"]["size"] = 1 # Type : 3
|
|
|
|
type_list["EBI"]["size"] = 1 # Type : 73
|
|
|
|
type_list["RAT Type"]["size"] = 1 # Type : 82
|
2021-10-16 08:26:30 +00:00
|
|
|
type_list["Delay Value"]["size"] = 1 # Type : 92
|
2021-06-21 13:36:38 +00:00
|
|
|
type_list["Charging ID"]["size"] = 4 # Type : 94
|
2017-03-15 13:28:04 +00:00
|
|
|
type_list["PDN Type"]["size"] = 1 # Type : 99
|
2019-12-28 12:46:30 +00:00
|
|
|
type_list["PTI"]["size"] = 1 # Type : 100
|
2017-03-15 13:28:04 +00:00
|
|
|
type_list["Port Number"]["size"] = 2 # Type : 126
|
|
|
|
type_list["APN Restriction"]["size"] = 1 # Type : 127
|
|
|
|
type_list["Selection Mode"]["size"] = 1 # Type : 128
|
2019-12-28 12:46:30 +00:00
|
|
|
type_list["Node Type"]["size"] = 1 # Type : 135
|
2020-03-25 21:43:02 +00:00
|
|
|
type_list["Node Features"]["size"] = 1 # Type : 152
|
2017-03-15 13:28:04 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
f = open(outdir + 'message.h', 'w')
|
2017-03-14 13:44:48 +00:00
|
|
|
output_header_to_file(f)
|
2019-09-13 12:07:47 +00:00
|
|
|
f.write("""#if !defined(OGS_GTP_INSIDE) && !defined(OGS_GTP_COMPILATION)
|
|
|
|
#error "This header cannot be included directly."
|
|
|
|
#endif
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
#ifndef OGS_GTP2_MESSAGE_H
|
|
|
|
#define OGS_GTP2_MESSAGE_H
|
2017-03-14 08:09:27 +00:00
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
2019-06-11 09:28:25 +00:00
|
|
|
#endif
|
2017-03-14 08:09:27 +00:00
|
|
|
|
2017-08-31 01:48:14 +00:00
|
|
|
/* 5.1 General format */
|
2019-09-13 12:07:47 +00:00
|
|
|
#define OGS_GTPV1U_HEADER_LEN 8
|
|
|
|
#define OGS_GTPV2C_HEADER_LEN 12
|
2022-04-12 22:07:39 +00:00
|
|
|
#define OGS_GTP2_TEID_LEN 4
|
|
|
|
typedef struct ogs_gtp2_header_s {
|
2017-08-31 01:48:14 +00:00
|
|
|
union {
|
|
|
|
struct {
|
2022-04-12 22:07:39 +00:00
|
|
|
#define OGS_GTP2_VERSION_0 0
|
|
|
|
#define OGS_GTP2_VERSION_1 1
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
If eg. PCRF or AAA diameter link is not yet ready (eg. PCRF crashed), and
a client sends a CreateSessionRequest announcing its ow F-TEID,
then open5gs-smfd answers with Create Session Response Cause=
"Remote peer not responding", but it is not setting the received F-TEID
in the header of the response, instead it sends with TEI=0.
As a result, the peer cannot match the CreateSessionResponse, and needs
to rely on its own timeout timer to figure out that specific request failed.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
|
|
|
|
#define OGS_GTP2_TEID_NO_PRESENCE 0
|
|
|
|
#define OGS_GTP2_TEID_PRESENCE 1
|
2019-04-27 14:54:30 +00:00
|
|
|
ED4(uint8_t version:3;,
|
|
|
|
uint8_t piggybacked:1;,
|
|
|
|
uint8_t teid_presence:1;,
|
|
|
|
uint8_t spare1:3;)
|
2017-08-31 01:48:14 +00:00
|
|
|
};
|
|
|
|
/* GTU-U flags */
|
2020-10-21 00:00:02 +00:00
|
|
|
#define OGS_GTPU_FLAGS_V 0x20
|
|
|
|
#define OGS_GTPU_FLAGS_PT 0x10
|
|
|
|
#define OGS_GTPU_FLAGS_E 0x04
|
|
|
|
#define OGS_GTPU_FLAGS_S 0x02
|
|
|
|
#define OGS_GTPU_FLAGS_PN 0x01
|
2019-04-27 14:54:30 +00:00
|
|
|
uint8_t flags;
|
2017-08-31 01:48:14 +00:00
|
|
|
};
|
2020-06-26 02:44:28 +00:00
|
|
|
/* GTP-U message type, defined in 3GPP TS 29.281 Release 11 */
|
|
|
|
#define OGS_GTPU_MSGTYPE_ECHO_REQ 1
|
|
|
|
#define OGS_GTPU_MSGTYPE_ECHO_RSP 2
|
|
|
|
#define OGS_GTPU_MSGTYPE_ERR_IND 26
|
|
|
|
#define OGS_GTPU_MSGTYPE_SUPP_EXTHDR_NOTI 31
|
|
|
|
#define OGS_GTPU_MSGTYPE_END_MARKER 254
|
|
|
|
#define OGS_GTPU_MSGTYPE_GPDU 255
|
2019-04-27 14:54:30 +00:00
|
|
|
uint8_t type;
|
|
|
|
uint16_t length;
|
2017-08-31 01:48:14 +00:00
|
|
|
union {
|
|
|
|
struct {
|
2019-04-27 14:54:30 +00:00
|
|
|
uint32_t teid;
|
2017-08-31 01:48:14 +00:00
|
|
|
/* sqn : 31bit ~ 8bit, spare : 7bit ~ 0bit */
|
2022-04-12 22:07:39 +00:00
|
|
|
#define OGS_GTP2_XID_TO_SQN(__xid) htobe32(((__xid) << 8))
|
|
|
|
#define OGS_GTP2_SQN_TO_XID(__sqn) (be32toh(__sqn) >> 8)
|
2019-04-27 14:54:30 +00:00
|
|
|
uint32_t sqn;
|
2017-08-31 01:48:14 +00:00
|
|
|
};
|
|
|
|
/* sqn : 31bit ~ 8bit, spare : 7bit ~ 0bit */
|
2019-04-27 14:54:30 +00:00
|
|
|
uint32_t sqn_only;
|
2017-08-31 01:48:14 +00:00
|
|
|
};
|
2022-04-12 22:07:39 +00:00
|
|
|
} __attribute__ ((packed)) ogs_gtp2_header_t;
|
2017-08-31 01:48:14 +00:00
|
|
|
|
|
|
|
/* GTPv2-C message type */
|
2017-03-14 08:09:27 +00:00
|
|
|
""")
|
|
|
|
|
|
|
|
tmp = [(k, v["type"]) for k, v in msg_list.items()]
|
|
|
|
sorted_msg_list = sorted(tmp, key=lambda tup: int(tup[1]))
|
|
|
|
for (k, v) in sorted_msg_list:
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write("#define OGS_GTP2_" + v_upper(k) + "_TYPE " + v + "\n")
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("\n")
|
2017-03-14 08:09:27 +00:00
|
|
|
|
|
|
|
tmp = [(k, v["type"]) for k, v in type_list.items()]
|
|
|
|
sorted_type_list = sorted(tmp, key=lambda tup: int(tup[1]))
|
|
|
|
for (k, v) in sorted_type_list:
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write("#define OGS_GTP2_" + v_upper(k) + "_TYPE " + v + "\n")
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("\n")
|
2017-03-14 08:09:27 +00:00
|
|
|
|
2021-10-23 23:37:11 +00:00
|
|
|
f.write("/* Information Element TLV Descriptor */\n")
|
2017-03-14 08:09:27 +00:00
|
|
|
for (k, v) in sorted_type_list:
|
2017-03-17 15:11:57 +00:00
|
|
|
if k in group_list.keys():
|
|
|
|
continue
|
|
|
|
for instance in range(0, int(type_list[k]["max_instance"])+1):
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write("extern ogs_tlv_desc_t ogs_gtp2_tlv_desc_" + v_lower(k))
|
2017-03-17 15:11:57 +00:00
|
|
|
f.write("_" + str(instance) + ";\n")
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("\n")
|
2017-03-14 08:09:27 +00:00
|
|
|
|
2020-07-01 04:22:55 +00:00
|
|
|
for k, v in group_list.items():
|
|
|
|
if v_lower(k) == "pc5_qos_parameters":
|
|
|
|
v["index"] = "1"
|
|
|
|
if v_lower(k) == "remote_ue_context":
|
|
|
|
v["index"] = "2"
|
2023-03-05 03:37:14 +00:00
|
|
|
if v_lower(k) == "pgw_change_info":
|
|
|
|
v["index"] = "3"
|
2020-07-01 04:22:55 +00:00
|
|
|
|
|
|
|
tmp = [(k, v["index"]) for k, v in group_list.items()]
|
2017-03-15 01:53:33 +00:00
|
|
|
sorted_group_list = sorted(tmp, key=lambda tup: int(tup[1]))
|
2017-03-15 05:10:34 +00:00
|
|
|
|
2021-10-23 23:37:11 +00:00
|
|
|
f.write("/* Group Information Element TLV Descriptor */\n")
|
2017-03-15 01:53:33 +00:00
|
|
|
for (k, v) in sorted_group_list:
|
2017-03-15 05:10:34 +00:00
|
|
|
for instance in range(0, int(type_list[k]["max_instance"])+1):
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write("extern ogs_tlv_desc_t ogs_gtp2_tlv_desc_" + v_lower(k))
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("_" + str(instance) + ";\n")
|
|
|
|
f.write("\n")
|
2017-03-14 12:02:15 +00:00
|
|
|
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("/* Message Descriptor */\n")
|
2017-03-15 07:07:52 +00:00
|
|
|
for (k, v) in sorted_msg_list:
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write("extern ogs_tlv_desc_t ogs_gtp2_tlv_desc_" + v_lower(k) + ";\n")
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("\n")
|
2017-03-15 07:07:52 +00:00
|
|
|
|
2021-10-23 23:37:11 +00:00
|
|
|
f.write("/* Structure for Information Element */\n")
|
2017-03-14 08:09:27 +00:00
|
|
|
for (k, v) in sorted_type_list:
|
2017-03-17 15:11:57 +00:00
|
|
|
if k in group_list.keys():
|
|
|
|
continue
|
|
|
|
if "size" in type_list[k]:
|
|
|
|
if type_list[k]["size"] == 1:
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write("typedef ogs_tlv_uint8_t ogs_gtp2_tlv_" + v_lower(k) + "_t;\n")
|
2017-03-17 15:11:57 +00:00
|
|
|
elif type_list[k]["size"] == 2:
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write("typedef ogs_tlv_uint16_t ogs_gtp2_tlv_" + v_lower(k) + "_t;\n")
|
2017-03-17 15:11:57 +00:00
|
|
|
elif type_list[k]["size"] == 3:
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write("typedef ogs_tlv_uint24_t ogs_gtp2_tlv_" + v_lower(k) + "_t;\n")
|
2017-03-17 15:11:57 +00:00
|
|
|
elif type_list[k]["size"] == 4:
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write("typedef ogs_tlv_uint32_t ogs_gtp2_tlv_" + v_lower(k) + "_t;\n")
|
2017-03-15 13:28:04 +00:00
|
|
|
else:
|
2017-03-17 15:11:57 +00:00
|
|
|
assert False, "Unknown size = %d for key = %s" % (type_list[k]["size"], k)
|
|
|
|
else:
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write("typedef ogs_tlv_octet_t ogs_gtp2_tlv_" + v_lower(k) + "_t;\n")
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("\n")
|
2017-03-14 08:09:27 +00:00
|
|
|
|
2021-10-23 23:37:11 +00:00
|
|
|
f.write("/* Structure for Group Information Element */\n")
|
2017-03-15 01:53:33 +00:00
|
|
|
for (k, v) in sorted_group_list:
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write("typedef struct ogs_gtp2_tlv_" + v_lower(k) + "_s {\n")
|
2019-09-13 12:07:47 +00:00
|
|
|
f.write(" ogs_tlv_presence_t presence;\n")
|
2017-03-15 07:26:29 +00:00
|
|
|
for ies in group_list[k]["ies"]:
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write(" ogs_gtp2_tlv_" + v_lower(ies["ie_type"]) + "_t " + \
|
2017-03-15 07:26:29 +00:00
|
|
|
v_lower(ies["ie_value"]))
|
|
|
|
if ies["ie_type"] == "F-TEID":
|
|
|
|
if ies["ie_value"] == "S2b-U ePDG F-TEID":
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("_" + ies["instance"] + ";")
|
2017-03-15 07:26:29 +00:00
|
|
|
elif ies["ie_value"] == "S2a-U TWAN F-TEID":
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("_" + ies["instance"] + ";")
|
2017-03-15 03:05:10 +00:00
|
|
|
else:
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write(";")
|
|
|
|
f.write(" /* Instance : " + ies["instance"] + " */\n")
|
2017-03-15 01:53:33 +00:00
|
|
|
else:
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write(";\n")
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write("} ogs_gtp2_tlv_" + v_lower(k) + "_t;\n")
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("\n")
|
2017-03-15 01:53:33 +00:00
|
|
|
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("/* Structure for Message */\n")
|
2017-03-15 07:07:52 +00:00
|
|
|
for (k, v) in sorted_msg_list:
|
|
|
|
if "ies" in msg_list[k]:
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write("typedef struct ogs_gtp2_" + v_lower(k) + "_s {\n")
|
2017-03-15 07:07:52 +00:00
|
|
|
for ies in msg_list[k]["ies"]:
|
2022-05-12 13:52:36 +00:00
|
|
|
if ((k == 'Create Indirect Data Forwarding Tunnel Request' or k == 'Create Indirect Data Forwarding Tunnel Response') and ies["ie_value"] == 'Bearer Contexts') or (k == 'Create Session Request' and ies["ie_value"] == 'Bearer Contexts to be created') or (k == 'Create Session Response' and ies["ie_value"] == 'Bearer Contexts created') or (k == 'Modify Bearer Request' and ies["ie_value"] == 'Bearer Contexts to be modified') or (k == 'Modify Bearer Response' and ies["ie_value"] == 'Bearer Contexts modified'):
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write(" ogs_gtp2_tlv_" + v_lower(ies["ie_type"]) + "_t " + \
|
2022-05-12 13:52:36 +00:00
|
|
|
v_lower(ies["ie_value"]) + "[OGS_BEARER_PER_UE];\n")
|
2020-07-09 05:38:09 +00:00
|
|
|
else:
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write(" ogs_gtp2_tlv_" + v_lower(ies["ie_type"]) + "_t " + \
|
2020-07-09 05:38:09 +00:00
|
|
|
v_lower(ies["ie_value"]) + ";\n")
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write("} ogs_gtp2_" + v_lower(k) + "_t;\n")
|
2017-03-29 10:31:39 +00:00
|
|
|
f.write("\n")
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write("typedef struct ogs_gtp2_message_s {\n")
|
|
|
|
f.write(" ogs_gtp2_header_t h;\n")
|
2017-03-29 10:31:39 +00:00
|
|
|
f.write(" union {\n")
|
|
|
|
for (k, v) in sorted_msg_list:
|
|
|
|
if "ies" in msg_list[k]:
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write(" ogs_gtp2_" + v_lower(k) + "_t " + v_lower(k) + ";\n");
|
2017-03-29 10:31:39 +00:00
|
|
|
f.write(" };\n");
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write("} ogs_gtp2_message_t;\n\n")
|
2017-03-15 07:07:52 +00:00
|
|
|
|
2022-06-29 12:15:51 +00:00
|
|
|
f.write("""int ogs_gtp2_parse_msg(ogs_gtp2_message_t *gtp2_message, ogs_pkbuf_t *pkbuf);
|
|
|
|
ogs_pkbuf_t *ogs_gtp2_build_msg(ogs_gtp2_message_t *gtp2_message);
|
2017-03-29 10:31:39 +00:00
|
|
|
|
|
|
|
#ifdef __cplusplus
|
2017-03-14 08:09:27 +00:00
|
|
|
}
|
2019-06-11 09:28:25 +00:00
|
|
|
#endif
|
2017-03-14 08:09:27 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
#endif /* OGS_GTP2_MESSAGE_H */
|
2017-03-14 08:09:27 +00:00
|
|
|
""")
|
|
|
|
f.close()
|
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
f = open(outdir + 'message.c', 'w')
|
2017-03-14 13:44:48 +00:00
|
|
|
output_header_to_file(f)
|
2019-09-13 12:07:47 +00:00
|
|
|
f.write("""#include "ogs-gtp.h"
|
2017-03-14 08:09:27 +00:00
|
|
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
for (k, v) in sorted_type_list:
|
2017-03-17 15:11:57 +00:00
|
|
|
if k in group_list.keys():
|
|
|
|
continue
|
|
|
|
for instance in range(0, int(type_list[k]["max_instance"])+1):
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write("ogs_tlv_desc_t ogs_gtp2_tlv_desc_%s_%d =\n" % (v_lower(k), instance))
|
2017-03-17 15:11:57 +00:00
|
|
|
f.write("{\n")
|
|
|
|
if "size" in type_list[k]:
|
|
|
|
if type_list[k]["size"] == 1:
|
2019-09-13 12:07:47 +00:00
|
|
|
f.write(" OGS_TLV_UINT8,\n")
|
2017-03-17 15:11:57 +00:00
|
|
|
elif type_list[k]["size"] == 2:
|
2019-09-13 12:07:47 +00:00
|
|
|
f.write(" OGS_TLV_UINT16,\n")
|
2017-03-17 15:11:57 +00:00
|
|
|
elif type_list[k]["size"] == 3:
|
2019-09-13 12:07:47 +00:00
|
|
|
f.write(" OGS_TLV_UINT24,\n")
|
2017-03-17 15:11:57 +00:00
|
|
|
elif type_list[k]["size"] == 4:
|
2019-09-13 12:07:47 +00:00
|
|
|
f.write(" OGS_TLV_UINT32,\n")
|
2017-03-15 13:28:04 +00:00
|
|
|
else:
|
2017-03-17 15:11:57 +00:00
|
|
|
assert False, "Unknown size = %d for key = %s" % (type_list[k]["size"], k)
|
|
|
|
else:
|
2019-09-13 12:07:47 +00:00
|
|
|
f.write(" OGS_TLV_VAR_STR,\n")
|
2017-03-17 15:11:57 +00:00
|
|
|
f.write(" \"%s\",\n" % k)
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write(" OGS_GTP2_%s_TYPE,\n" % v_upper(k))
|
2017-03-17 15:11:57 +00:00
|
|
|
if "size" in type_list[k]:
|
|
|
|
f.write(" %d,\n" % type_list[k]["size"])
|
|
|
|
else:
|
|
|
|
f.write(" 0,\n")
|
|
|
|
f.write(" %d,\n" % instance)
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write(" sizeof(ogs_gtp2_tlv_%s_t),\n" % v_lower(k))
|
2017-03-17 15:11:57 +00:00
|
|
|
f.write(" { NULL }\n")
|
|
|
|
f.write("};\n\n")
|
2017-03-15 05:10:34 +00:00
|
|
|
|
|
|
|
for (k, v) in sorted_group_list:
|
|
|
|
for instance in range(0, int(type_list[k]["max_instance"])+1):
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write("ogs_tlv_desc_t ogs_gtp2_tlv_desc_%s_%d =\n" % (v_lower(k), instance))
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("{\n")
|
2019-09-13 12:07:47 +00:00
|
|
|
f.write(" OGS_TLV_COMPOUND,\n")
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write(" \"%s\",\n" % k)
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write(" OGS_GTP2_%s_TYPE,\n" % v_upper(k))
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write(" 0,\n")
|
|
|
|
f.write(" %d,\n" % instance)
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write(" sizeof(ogs_gtp2_tlv_%s_t),\n" % v_lower(k))
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write(" {\n")
|
2017-03-15 07:26:29 +00:00
|
|
|
for ies in group_list[k]["ies"]:
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write(" &ogs_gtp2_tlv_desc_%s_%s,\n" % (v_lower(ies["ie_type"]), v_lower(ies["instance"])))
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write(" NULL,\n")
|
|
|
|
f.write(" }\n")
|
|
|
|
f.write("};\n\n")
|
2017-03-15 01:53:33 +00:00
|
|
|
|
2017-03-15 07:20:13 +00:00
|
|
|
for (k, v) in sorted_msg_list:
|
|
|
|
if "ies" in msg_list[k]:
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write("ogs_tlv_desc_t ogs_gtp2_tlv_desc_%s =\n" % v_lower(k))
|
2017-03-29 10:31:39 +00:00
|
|
|
f.write("{\n")
|
2019-09-13 12:07:47 +00:00
|
|
|
f.write(" OGS_TLV_MESSAGE,\n")
|
2017-03-29 10:31:39 +00:00
|
|
|
f.write(" \"%s\",\n" % k)
|
|
|
|
f.write(" 0, 0, 0, 0, {\n")
|
2017-03-15 07:20:13 +00:00
|
|
|
for ies in msg_list[k]["ies"]:
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write(" &ogs_gtp2_tlv_desc_%s_%s,\n" % (v_lower(ies["ie_type"]), v_lower(ies["instance"])))
|
2022-05-12 13:52:36 +00:00
|
|
|
if ((k == 'Create Indirect Data Forwarding Tunnel Request' or k == 'Create Indirect Data Forwarding Tunnel Response') and ies["ie_value"] == 'Bearer Contexts') or (k == 'Create Session Request' and ies["ie_value"] == 'Bearer Contexts to be created') or (k == 'Create Session Response' and ies["ie_value"] == 'Bearer Contexts created') or (k == 'Modify Bearer Request' and ies["ie_value"] == 'Bearer Contexts to be modified') or (k == 'Modify Bearer Response' and ies["ie_value"] == 'Bearer Contexts modified'):
|
2020-07-09 05:38:09 +00:00
|
|
|
f.write(" &ogs_tlv_desc_more8,\n")
|
2017-03-29 10:31:39 +00:00
|
|
|
f.write(" NULL,\n")
|
|
|
|
f.write("}};\n\n")
|
|
|
|
f.write("\n")
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
f.write("""int ogs_gtp2_parse_msg(ogs_gtp2_message_t *gtp2_message, ogs_pkbuf_t *pkbuf)
|
2017-03-29 10:31:39 +00:00
|
|
|
{
|
2019-04-27 14:54:30 +00:00
|
|
|
int rv = OGS_ERROR;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_header_t *h = NULL;
|
2019-04-27 14:54:30 +00:00
|
|
|
uint16_t size = 0;
|
2017-08-31 03:06:11 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_assert(gtp2_message);
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(pkbuf);
|
|
|
|
ogs_assert(pkbuf->len);
|
2018-01-23 07:48:40 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
h = (ogs_gtp2_header_t *)pkbuf->data;
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(h);
|
2022-04-29 12:28:16 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
memset(gtp2_message, 0, sizeof(ogs_gtp2_message_t));
|
2017-08-31 03:06:11 +00:00
|
|
|
|
|
|
|
if (h->teid_presence)
|
2019-09-13 12:07:47 +00:00
|
|
|
size = OGS_GTPV2C_HEADER_LEN;
|
2017-08-31 03:06:11 +00:00
|
|
|
else
|
2022-04-12 22:07:39 +00:00
|
|
|
size = OGS_GTPV2C_HEADER_LEN-OGS_GTP2_TEID_LEN;
|
2017-08-31 03:06:11 +00:00
|
|
|
|
2023-03-04 23:35:30 +00:00
|
|
|
if (ogs_pkbuf_pull(pkbuf, size) == NULL) {
|
|
|
|
ogs_error("ogs_pkbuf_pull() failed [len:%d]", pkbuf->len);
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2022-04-12 22:07:39 +00:00
|
|
|
memcpy(>p2_message->h, pkbuf->data - size, size);
|
2017-08-31 03:06:11 +00:00
|
|
|
|
|
|
|
if (h->teid_presence)
|
2022-04-29 12:28:16 +00:00
|
|
|
gtp2_message->h.teid = be32toh(gtp2_message->h.teid);
|
2017-08-31 03:06:11 +00:00
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
if (pkbuf->len == 0) {
|
|
|
|
ogs_assert(ogs_pkbuf_push(pkbuf, size));
|
2019-04-27 14:54:30 +00:00
|
|
|
return OGS_OK;
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
2017-09-14 05:18:47 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
switch(gtp2_message->h.type) {
|
2017-03-29 10:31:39 +00:00
|
|
|
""")
|
|
|
|
for (k, v) in sorted_msg_list:
|
|
|
|
if "ies" in msg_list[k]:
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write(" case OGS_GTP2_%s_TYPE:\n" % v_upper(k))
|
2023-08-26 07:28:42 +00:00
|
|
|
if k != "Delete Indirect Data Forwarding Tunnel Request":
|
|
|
|
f.write(" rv = ogs_tlv_parse_msg(>p2_message->%s,\n" % v_lower(k))
|
|
|
|
f.write(" &ogs_gtp2_tlv_desc_%s, pkbuf, OGS_TLV_MODE_T1_L2_I1);\n" % v_lower(k))
|
2023-08-26 07:35:27 +00:00
|
|
|
f.write(" break;\n")
|
2019-12-01 11:14:47 +00:00
|
|
|
f.write(""" default:
|
2022-08-24 12:02:28 +00:00
|
|
|
ogs_warn("Not implemented(type:%d)", gtp2_message->h.type);
|
2019-12-01 11:14:47 +00:00
|
|
|
break;
|
2017-04-02 13:30:58 +00:00
|
|
|
}
|
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(ogs_pkbuf_push(pkbuf, size));
|
|
|
|
|
2017-04-02 13:30:58 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
""")
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
f.write("""ogs_pkbuf_t *ogs_gtp2_build_msg(ogs_gtp2_message_t *gtp2_message)
|
2017-04-02 13:30:58 +00:00
|
|
|
{
|
2019-11-30 07:45:09 +00:00
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
2017-04-02 13:30:58 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_assert(gtp2_message);
|
|
|
|
switch(gtp2_message->h.type) {
|
2017-04-02 13:30:58 +00:00
|
|
|
""")
|
|
|
|
for (k, v) in sorted_msg_list:
|
|
|
|
if "ies" in msg_list[k]:
|
2022-04-12 22:07:39 +00:00
|
|
|
f.write(" case OGS_GTP2_%s_TYPE:\n" % v_upper(k))
|
|
|
|
f.write(" pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_%s,\n" % v_lower(k))
|
|
|
|
f.write(" >p2_message->%s, OGS_TLV_MODE_T1_L2_I1);\n" % v_lower(k))
|
2019-11-30 07:45:09 +00:00
|
|
|
f.write(" break;\n")
|
|
|
|
f.write(""" default:
|
2022-08-24 12:02:28 +00:00
|
|
|
ogs_warn("Not implemented(type:%d)", gtp2_message->h.type);
|
2019-11-30 07:45:09 +00:00
|
|
|
break;
|
2017-03-29 10:31:39 +00:00
|
|
|
}
|
|
|
|
|
2019-11-30 07:45:09 +00:00
|
|
|
return pkbuf;
|
2017-03-29 10:31:39 +00:00
|
|
|
}
|
|
|
|
""")
|
2017-03-15 07:20:13 +00:00
|
|
|
|
2017-03-14 08:09:27 +00:00
|
|
|
f.close()
|