add initial code for NAS message generating script

This commit is contained in:
Sukchan Lee 2017-03-18 00:11:57 +09:00
parent 5d034518eb
commit bfb3fdcae3
13 changed files with 656 additions and 70 deletions

View File

@ -377,10 +377,11 @@ f.write("\n")
f.write("/* Infomration Element TLV Descriptor */\n")
for (k, v) in sorted_type_list:
if k not in group_list.keys():
for instance in range(0, int(type_list[k]["max_instance"])+1):
f.write("extern tlv_desc_t gtpv2c_desc_" + v_lower(k))
f.write("_" + str(instance) + ";\n")
if k in group_list.keys():
continue
for instance in range(0, int(type_list[k]["max_instance"])+1):
f.write("extern tlv_desc_t gtpv2c_desc_" + v_lower(k))
f.write("_" + str(instance) + ";\n")
f.write("\n")
tmp = [(k, v["type"]) for k, v in group_list.items()]
@ -400,20 +401,21 @@ f.write("\n")
f.write("/* Structure for Infomration Element */\n")
for (k, v) in sorted_type_list:
if k not in group_list.keys():
if "size" in type_list[k]:
if type_list[k]["size"] == 1:
f.write("typedef tlv_uint8_t gtpv2c_" + v_lower(k) + "_t;\n")
elif type_list[k]["size"] == 2:
f.write("typedef tlv_uint16_t gtpv2c_" + v_lower(k) + "_t;\n")
elif type_list[k]["size"] == 3:
f.write("typedef tlv_uint24_t gtpv2c_" + v_lower(k) + "_t;\n")
elif type_list[k]["size"] == 4:
f.write("typedef tlv_uint32_t gtpv2c_" + v_lower(k) + "_t;\n")
else:
assert False, "Unknown size = %d for key = %s" % (type_list[k]["size"], k)
if k in group_list.keys():
continue
if "size" in type_list[k]:
if type_list[k]["size"] == 1:
f.write("typedef tlv_uint8_t gtpv2c_" + v_lower(k) + "_t;\n")
elif type_list[k]["size"] == 2:
f.write("typedef tlv_uint16_t gtpv2c_" + v_lower(k) + "_t;\n")
elif type_list[k]["size"] == 3:
f.write("typedef tlv_uint24_t gtpv2c_" + v_lower(k) + "_t;\n")
elif type_list[k]["size"] == 4:
f.write("typedef tlv_uint32_t gtpv2c_" + v_lower(k) + "_t;\n")
else:
f.write("typedef tlv_octet_t gtpv2c_" + v_lower(k) + "_t;\n")
assert False, "Unknown size = %d for key = %s" % (type_list[k]["size"], k)
else:
f.write("typedef tlv_octet_t gtpv2c_" + v_lower(k) + "_t;\n")
f.write("\n")
f.write("/* Structure for Group Infomration Element */\n")
@ -461,33 +463,34 @@ f.write("""#include "gtpv2c_tlv.h"
""")
for (k, v) in sorted_type_list:
if k not in group_list.keys():
for instance in range(0, int(type_list[k]["max_instance"])+1):
f.write("tlv_desc_t gtpv2c_desc_%s_%d =\n" % (v_lower(k), instance))
f.write("{\n")
if "size" in type_list[k]:
if type_list[k]["size"] == 1:
f.write(" TLV_UINT8,\n")
elif type_list[k]["size"] == 2:
f.write(" TLV_UINT16,\n")
elif type_list[k]["size"] == 3:
f.write(" TLV_UINT24,\n")
elif type_list[k]["size"] == 4:
f.write(" TLV_UINT32,\n")
else:
assert False, "Unknown size = %d for key = %s" % (type_list[k]["size"], k)
if k in group_list.keys():
continue
for instance in range(0, int(type_list[k]["max_instance"])+1):
f.write("tlv_desc_t gtpv2c_desc_%s_%d =\n" % (v_lower(k), instance))
f.write("{\n")
if "size" in type_list[k]:
if type_list[k]["size"] == 1:
f.write(" TLV_UINT8,\n")
elif type_list[k]["size"] == 2:
f.write(" TLV_UINT16,\n")
elif type_list[k]["size"] == 3:
f.write(" TLV_UINT24,\n")
elif type_list[k]["size"] == 4:
f.write(" TLV_UINT32,\n")
else:
f.write(" TLV_VAR_STR,\n")
f.write(" \"%s\",\n" % k)
f.write(" GTPV2C_IE_%s_TYPE,\n" % v_upper(k))
if "size" in type_list[k]:
f.write(" %d,\n" % type_list[k]["size"])
else:
f.write(" 0,\n")
f.write(" %d,\n" % instance)
f.write(" sizeof(gtpv2c_%s_t),\n" % v_lower(k))
f.write(" { NULL }\n")
f.write("};\n\n")
assert False, "Unknown size = %d for key = %s" % (type_list[k]["size"], k)
else:
f.write(" TLV_VAR_STR,\n")
f.write(" \"%s\",\n" % k)
f.write(" GTPV2C_IE_%s_TYPE,\n" % v_upper(k))
if "size" in type_list[k]:
f.write(" %d,\n" % type_list[k]["size"])
else:
f.write(" 0,\n")
f.write(" %d,\n" % instance)
f.write(" sizeof(gtpv2c_%s_t),\n" % v_lower(k))
f.write(" { NULL }\n")
f.write("};\n\n")
for (k, v) in sorted_group_list:
for instance in range(0, int(type_list[k]["max_instance"])+1):

View File

@ -5,11 +5,11 @@
c_int32_t nas_decode_attach_request(nas_message_t *message, pkbuf_t *pkbuf)
{
nas_attach_request_t *attach_request = &message->emm.attach_request;
nas_attach_request_t *attach_request = &message->attach_request;
c_uint16_t decoded = 0;
c_int32_t size = 0;
size = nas_decode_attach_type(&attach_request->attach_type, pkbuf);
size = nas_decode_eps_attach_type(&attach_request->eps_attach_type, pkbuf);
d_assert(size >= 0, return -1, "decode failed");
decoded += size;
@ -204,7 +204,7 @@ c_int32_t nas_decode_attach_request(nas_message_t *message, pkbuf_t *pkbuf)
c_int32_t nas_decode_attach_complete(nas_message_t *message, pkbuf_t *pkbuf)
{
nas_attach_complete_t *attach_complete = &message->emm.attach_complete;
nas_attach_complete_t *attach_complete = &message->attach_complete;
c_uint16_t decoded = 0;
c_int32_t size = 0;
@ -220,7 +220,7 @@ c_int32_t nas_decode_authentication_failure(nas_message_t *message,
pkbuf_t *pkbuf)
{
nas_authentication_failure_t *authentication_failure =
&message->emm.authentication_failure;
&message->authentication_failure;
c_uint16_t decoded = 0;
c_int32_t size = 0;
@ -263,7 +263,7 @@ c_int32_t nas_decode_authentication_response(nas_message_t *message,
pkbuf_t *pkbuf)
{
nas_authentication_response_t *authentication_response =
&message->emm.authentication_response;
&message->authentication_response;
c_uint16_t decoded = 0;
c_int32_t size = 0;
@ -279,7 +279,7 @@ c_int32_t nas_decode_security_mode_complete(nas_message_t *message,
pkbuf_t *pkbuf)
{
nas_security_mode_complete_t *security_mode_complete =
&message->emm.security_mode_complete;
&message->security_mode_complete;
c_uint16_t decoded = 0;
c_int32_t size = 0;
@ -317,7 +317,7 @@ c_int32_t nas_decode_security_mode_reject(nas_message_t *message,
pkbuf_t *pkbuf)
{
nas_security_mode_reject_t *security_mode_reject =
&message->emm.security_mode_reject;
&message->security_mode_reject;
c_uint16_t decoded = 0;
c_int32_t size = 0;

View File

@ -5,7 +5,7 @@
c_int32_t nas_encode_attach_accept(pkbuf_t *pkbuf, nas_message_t *message)
{
nas_attach_accept_t *attach_accept = &message->emm.attach_accept;
nas_attach_accept_t *attach_accept = &message->attach_accept;
c_int32_t size = 0;
c_int32_t encoded = 0;
@ -182,7 +182,7 @@ c_int32_t nas_encode_attach_accept(pkbuf_t *pkbuf, nas_message_t *message)
c_int32_t nas_encode_attach_reject(pkbuf_t *pkbuf, nas_message_t *message)
{
nas_attach_reject_t *attach_reject = &message->emm.attach_reject;
nas_attach_reject_t *attach_reject = &message->attach_reject;
c_int32_t size = 0;
c_int32_t encoded = 0;
@ -247,7 +247,7 @@ c_int32_t nas_encode_authentication_request(
pkbuf_t *pkbuf, nas_message_t *message)
{
nas_authentication_request_t *authentication_request =
&message->emm.authentication_request;
&message->authentication_request;
c_int32_t size = 0;
c_int32_t encoded = 0;
@ -273,7 +273,7 @@ c_int32_t nas_encode_security_mode_command(
pkbuf_t *pkbuf, nas_message_t *message)
{
nas_security_mode_command_t *security_mode_command =
&message->emm.security_mode_command;
&message->security_mode_command;
c_int32_t size = 0;
c_int32_t encoded = 0;

View File

@ -363,15 +363,15 @@ c_int32_t nas_encode_attach_result(
* M V 1/2
* 9.9.3.21 NAS key set identifier
* M V 1/2 */
c_int32_t nas_decode_attach_type(
nas_attach_type_t *attach_type, pkbuf_t *pkbuf)
c_int32_t nas_decode_eps_attach_type(
nas_eps_attach_type_t *eps_attach_type, pkbuf_t *pkbuf)
{
c_uint16_t size = 0;
size = sizeof(nas_attach_type_t);
size = sizeof(nas_eps_attach_type_t);
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK,
return -1, "pkbuf_header error");
memcpy(attach_type, pkbuf->payload - size, size);
memcpy(eps_attach_type, pkbuf->payload - size, size);
return size;
}

View File

@ -362,15 +362,15 @@ CORE_DECLARE(c_int32_t) nas_encode_attach_result(
#define NAS_ATTACH_TYPE_COMBINED_EPS_IMSI_ATTAACH 2
#define NAS_ATTACH_TYPE_EPS_ERMERGENCY_ATTCH 3
#define NAS_ATTACH_TYPE_RESERVED 4
typedef struct _nas_attach_type_t {
typedef struct _nas_eps_attach_type_t {
ED4(c_uint8_t tsc:1;,
c_uint8_t nas_key_set_identifier:3;,
c_uint8_t spare:1;,
c_uint8_t attach_type:3;)
} __attribute__ ((packed)) nas_attach_type_t;
} __attribute__ ((packed)) nas_eps_attach_type_t;
CORE_DECLARE(c_int32_t) nas_decode_attach_type(
nas_attach_type_t *attach_type, pkbuf_t *pkbuf);
CORE_DECLARE(c_int32_t) nas_decode_eps_attach_type(
nas_eps_attach_type_t *eps_attach_type, pkbuf_t *pkbuf);
/* 9.9.3.12 EPS mobile identity
* M LV 5-12 */

View File

@ -228,7 +228,7 @@ typedef struct _nas_attach_reject {
typedef struct _nas_attach_request_t {
/* Mandatory fields */
nas_attach_type_t attach_type;
nas_eps_attach_type_t eps_attach_type;
nas_eps_mobile_identity_t eps_mobile_identity;
nas_ue_network_capability_t ue_network_capability;
nas_esm_message_container_t esm_message_container;
@ -356,7 +356,7 @@ typedef struct _nas_message_t {
nas_security_mode_command_t security_mode_command;
nas_security_mode_complete_t security_mode_complete;
nas_security_mode_reject_t security_mode_reject;
} emm;
};
} nas_message_t;
CORE_DECLARE(int) nas_plain_decode(nas_message_t *message, pkbuf_t *pkbuf);

Binary file not shown.

16
lib/nas/support/README Normal file
View File

@ -0,0 +1,16 @@
* Install python-pip
user@host ~/Documents/git/cellwire/lib/gtp/support$ \
sudo apt-get install python-pip
* Install python-docx
user@host ~/Documents/git/cellwire/lib/gtp/support$ \
sudo pip install python-docx
* Change the format of standard specification
from 24301-d80.doc to 24301-d80.docx
using Microsoft Office 2007+
* Generate Message support files
user@host ~/Documents/git/cellwire/lib/s1ap/support$ \
python nas_message.py -f 24301-d80.docx -o ..

25
lib/nas/support/cache/nas_msg_65.py vendored Normal file
View File

@ -0,0 +1,25 @@
ies = []
ies.append({ "iei" : "", "value" : "EPS attach type", "type" : "EPS attach type", "reference" : "9.9.3.11", "presence" : "M", "format" : "V", "length" : "1/2"})
ies.append({ "iei" : "", "value" : "EPS mobile identity", "type" : "EPS mobile identity", "reference" : "9.9.3.12", "presence" : "M", "format" : "LV", "length" : "5-12"})
ies.append({ "iei" : "", "value" : "UE network capability", "type" : "UE network capability", "reference" : "9.9.3.34", "presence" : "M", "format" : "LV", "length" : "3-14"})
ies.append({ "iei" : "", "value" : "ESM message container", "type" : "ESM message container", "reference" : "9.9.3.15", "presence" : "M", "format" : "LV-E", "length" : "5-n"})
ies.append({ "iei" : "19", "value" : "Old P-TMSI signature", "type" : "P-TMSI signature", "reference" : "P-9.9.3.26", "presence" : "O", "format" : "TV", "length" : "4"})
ies.append({ "iei" : "50", "value" : "Additional GUTI", "type" : "EPS mobile identity", "reference" : "9.9.3.12", "presence" : "O", "format" : "TLV", "length" : "13"})
ies.append({ "iei" : "52", "value" : "Last visited registered TAI", "type" : "Tracking area identity", "reference" : "9.9.3.32", "presence" : "O", "format" : "TV", "length" : "6"})
ies.append({ "iei" : "5C", "value" : "DRX parameter", "type" : "DRX parameter", "reference" : "9.9.3.8", "presence" : "O", "format" : "TV", "length" : "3"})
ies.append({ "iei" : "31", "value" : "MS network capability", "type" : "MS network capability", "reference" : "9.9.3.20", "presence" : "O", "format" : "TLV", "length" : "4-10"})
ies.append({ "iei" : "13", "value" : "Old location area identification", "type" : "Location area identification", "reference" : "9.9.2.2", "presence" : "O", "format" : "TV", "length" : "6"})
ies.append({ "iei" : "9-", "value" : "TMSI status", "type" : "TMSI status", "reference" : "9.9.3.31", "presence" : "O", "format" : "TV", "length" : "1"})
ies.append({ "iei" : "11", "value" : "Mobile station classmark 2", "type" : "Mobile station classmark 2", "reference" : "Mobile station classmark 29.9.2.4", "presence" : "O", "format" : "TLV", "length" : "5"})
ies.append({ "iei" : "20", "value" : "Mobile station classmark 3", "type" : "Mobile station classmark 3", "reference" : "Mobile station classmark 39.9.2.5", "presence" : "O", "format" : "TLV", "length" : "2-34"})
ies.append({ "iei" : "40", "value" : "Supported Codecs", "type" : "Supported Codec List", "reference" : "9.9.2.10", "presence" : "O", "format" : "TLV", "length" : "5-n"})
ies.append({ "iei" : "F-", "value" : "Additional update type", "type" : "Additional update type", "reference" : "9.9.3.0B", "presence" : "O", "format" : "TV", "length" : "1"})
ies.append({ "iei" : "5D", "value" : "Voice domain preference and UE's usage setting", "type" : "Voice domain preference and UE usage setting", "reference" : "Voice domain preference and UE'9.9.3.44", "presence" : "O", "format" : "TLV", "length" : "3"})
ies.append({ "iei" : "D-", "value" : "Device properties", "type" : "Device properties", "reference" : "9.9.2.0A", "presence" : "O", "format" : "TV", "length" : "1"})
ies.append({ "iei" : "E-", "value" : "Old GUTI type", "type" : "GUTI type", "reference" : "9.9.3.45", "presence" : "O", "format" : "TV", "length" : "1"})
ies.append({ "iei" : "C- ", "value" : "MS network feature support", "type" : "MS network feature support", "reference" : "9.9.3.20A", "presence" : "O", "format" : "TV", "length" : "1"})
ies.append({ "iei" : "10", "value" : "TMSI based NRI container", "type" : "Network resource identifier container", "reference" : "9.9.3.24A", "presence" : "O", "format" : "TLV", "length" : "4"})
ies.append({ "iei" : "6A", "value" : "T3324 value", "type" : "GPRS timer 2", "reference" : "GPRS timer 29.9.3.16A", "presence" : "O", "format" : "TLV", "length" : "3"})
ies.append({ "iei" : "5E", "value" : "T3412 extended value", "type" : "GPRS timer 3", "reference" : "GPRS timer 39.9.3.16B", "presence" : "O", "format" : "TLV", "length" : "3"})
ies.append({ "iei" : "6E", "value" : "Extended DRX parameters", "type" : "Extended DRX parameters", "reference" : "9.9.3.46", "presence" : "O", "format" : "TLV", "length" : "3"})
msg_list[key]["ies"] = ies

View File

@ -0,0 +1,542 @@
#
# Copyright (c) 2017, CellWire Group
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
from docx import Document
import re, os, sys, string
import datetime
import getopt
import getpass
version = "0.1.0"
msg_list = {}
type_list = {}
verbosity = 0
filename = ""
outdir = './'
cachedir = './cache/'
FAIL = '\033[91m'
INFO = '\033[93m'
ENDC = '\033[0m'
def d_print(string):
if verbosity > 0:
sys.stdout.write(string)
def d_info(string):
sys.stdout.write(INFO + string + ENDC + "\n")
def d_error(string):
sys.stderr.write(FAIL + string + ENDC + "\n")
sys.exit(0)
def write_file(f, string):
f.write(string)
d_print(string)
def output_header_to_file(f):
now = datetime.datetime.now()
f.write("""/*
* Copyright (c) 2017, CellWire Group
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
""")
f.write("/*******************************************************************************\n")
f.write(" * This file had been created by gtpv2c_tlv.py script v%s\n" % (version))
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")
def usage():
print "Python generating NAS Message encoder/decoder v%s" % (version)
print "Usage: python nas_message.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"
def v_upper(v):
return re.sub('3GPP', '', re.sub('\'', '_', re.sub('/', '_', re.sub('-', '_', re.sub(' ', '_', v)))).upper())
def v_lower(v):
return re.sub('3gpp', '', re.sub('\'', '_', re.sub('/', '_', re.sub('-', '_', re.sub(' ', '_', v)))).lower())
def get_cells(cells):
iei = cells[0].text.encode('ascii', 'ignore')
value = cells[1].text.encode('ascii', 'ignore')
type = re.sub("'s", "", re.sub('\s*\n\s*[a-zA-Z0-9.]*', '', cells[2].text)).encode('ascii', 'ignore')
reference = re.sub('[a-zA-Z\s]*\n\s*', '', cells[2].text).encode('ascii', 'ignore')
presence = cells[3].text.encode('ascii', 'ignore')
format = cells[4].text.encode('ascii', 'ignore')
length = cells[5].text.encode('ascii', 'ignore')
return { "iei" : iei, "value" : value, "type" : type, "reference" : reference, "presence" : presence, "format" : format, "length" : length }
def write_cells_to_file(name, cells):
write_file(f, name + ".append({ \"iei\" : \"" + cells["iei"] + \
"\", \"value\" : \"" + cells["value"] + \
"\", \"type\" : \"" + cells["type"] + \
"\", \"reference\" : \"" + cells["reference"] + \
"\", \"presence\" : \"" + cells["presence"] + \
"\", \"format\" : \"" + cells["format"] + \
"\", \"length\" : \"" + cells["length"] + "\"})\n")
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"):
cache = a
if cachedir.rfind('/') != len(cachedir):
cachedir += '/'
if o in ("-h", "--help"):
usage()
sys.exit(2)
# Message Type List
msg_list["ATTACH REQUEST"] = { "type" : "65" }
msg_list["ATTACH ACCEPT"]= { "type" : "66" }
msg_list["ATTACH COMPLETE"] = { "type" : "67" }
msg_list["ATTACH REJECT"] = { "type" : "68" }
msg_list["DETACH REQUEST"] = { "type" : "69" }
msg_list["DETACH ACCEPT"] = { "type" : "70" }
msg_list["TRACKING AREA UPDATE REQUEST"] = { "type" : "72" }
msg_list["TRACKING AREA UPDATE ACCEPT"] = { "type" : "73" }
msg_list["TRACKING AREA UPDATE COMPLETE"] = { "type" : "74" }
msg_list["TRACKING AREA UPDATE REJECT"] = { "type" : "75" }
msg_list["EXTENDED SERVICE REQUEST"] = { "type" : "76" }
msg_list["SERVICE REJECT"] = { "type" : "78" }
msg_list["GUTI REALLOCATION COMMAND"] = { "type" : "80" }
msg_list["GUTI REALLOCATION COMPLETE"] = { "type" : "81" }
msg_list["AUTHENTICATION REQUEST"] = { "type" : "82" }
msg_list["AUTHENTICATION RESPONSE"] = { "type" : "83" }
msg_list["AUTHENTICATION REJECT"] = { "type" : "84" }
msg_list["AUTHENTICATION FAILURE"] = { "type" : "92" }
msg_list["IDENTITY REQUEST"] = { "type" : "85" }
msg_list["IDENTITY RESPONSE"] = { "type" : "86" }
msg_list["SECURITY MODE COMMAND"] = { "type" : "93" }
msg_list["SECURITY MODE COMPLETE"] = { "type" : "94" }
msg_list["SECURITY MODE REJECT"] = { "type" : "95" }
msg_list["EMM STATUS"] = { "type" : "96" }
msg_list["EMM INFORMATION"] = { "type" : "97" }
msg_list["DOWNLINK NAS TRANSPORT"] = { "type" : "98" }
msg_list["UPLINK NAS TRANSPORT"] = { "type" : "99" }
msg_list["CS SERVICE NOTIFICATION"] = { "type" : "100" }
msg_list["DOWNLINK GENERIC NAS TRANSPORT"] = { "type" : "104" }
msg_list["UPLINK GENERIC NAS TRANSPORT"] = { "type" : "101" }
msg_list["ACTIVATE DEFAULT EPS BEARER CONTEXT REQUEST"] = { "type" : "193" }
msg_list["ACTIVATE DEFAULT EPS BEARER CONTEXT ACCEPT"] = { "type" : "194" }
msg_list["ACTIVATE DEFAULT EPS BEARER CONTEXT REJECT"] = { "type" : "195" }
msg_list["ACTIVATE DEDICATED EPS BEARER CONTEXT REQUEST"] = { "type" : "197" }
msg_list["ACTIVATE DEDICATED EPS BEARER CONTEXT ACCEPT"] = { "type" : "198" }
msg_list["ACTIVATE DEDICATED EPS BEARER CONTEXT REJECT"] = { "type" : "199" }
msg_list["MODIFY EPS BEARER CONTEXT REQUEST"] = { "type" : "201" }
msg_list["MODIFY EPS BEARER CONTEXT ACCEPT"] = { "type" : "202" }
msg_list["MODIFY EPS BEARER CONTEXT REJECT"] = { "type" : "203" }
msg_list["DEACTIVATE EPS BEARER CONTEXT REQUEST"] = { "type" : "205" }
msg_list["DEACTIVATE EPS BEARER CONTEXT ACCEPT"] = { "type" : "206" }
msg_list["PDN CONNECTIVITY REQUEST"] = { "type" : "208" }
msg_list["PDN CONNECTIVITY REJECT"] = { "type" : "209" }
msg_list["PDN DISCONNECT REQUEST"] = { "type" : "210" }
msg_list["PDN DISCONNECT REJECT"] = { "type" : "211" }
msg_list["BEARER RESOURCE ALLOCATION REQUEST"] = { "type" : "212" }
msg_list["BEARER RESOURCE ALLOCATION REJECT"] = { "type" : "213" }
msg_list["BEARER RESOURCE MODIFICATION REQUEST"] = { "type" : "214" }
msg_list["BEARER RESOURCE MODIFICATION REJECT"] = { "type" : "215" }
msg_list["ESM INFORMATION REQUEST"] = { "type" : "217" }
msg_list["ESM INFORMATION RESPONSE"] = { "type" : "218" }
msg_list["ESM STATUS"] = { "type" : "232" }
# Table number for Message List
msg_list["ATTACH REQUEST"]["table"] = 11
for key in msg_list.keys():
if "table" not in msg_list[key].keys():
continue;
d_info("[" + key + "]")
cachefile = cachedir + "nas_msg_" + msg_list[key]["type"] + ".py"
if os.path.isfile(cachefile) and os.access(cachefile, os.R_OK):
execfile(cachefile)
print "Read from " + cachefile
else:
document = Document(filename)
f = open(cachefile, 'w')
ies = []
write_file(f, "ies = []\n")
table = document.tables[msg_list[key]["table"]]
half_length = True;
for row in table.rows[4:]:
cells = get_cells(row.cells)
if cells is None:
continue
if cells["length"] == "1/2":
if half_length is True:
half_length = False;
else:
half_length = True;
continue;
ies.append(cells)
write_cells_to_file("ies", cells)
msg_list[key]["ies"] = ies
write_file(f, "msg_list[key][\"ies\"] = ies\n")
f.close()
f = open(outdir + 'nas_message2.h', 'w')
output_header_to_file(f)
f.write("""#ifndef __NAS_MESSAGE_H__
#define __NAS_MESSAGE_H__
#include "3gpp_message.h"
#include "nas_ies.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* The Packet Buffer(pkbuf_t) for NAS message MUST make a HEADROOM.
* When calculating AES_CMAC, we need to use the headroom of the packet. */
#define NAS_HEADROOM 16
#define NAS_SECURITY_HEADER_PLAIN_NAS_MESSAGE 0
#define NAS_SECURITY_HEADER_INTEGRITY_PROTECTED 1
#define NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED 2
#define NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_NEW_SECURITY_CONTEXT 3
#define NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHTERD_WITH_NEW_INTEGRITY_CONTEXT 4
#define NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_PARTICALLY_CIPHTERD 5
#define NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE 6
#define NAS_PROTOCOL_DISCRIMINATOR_ESM 0x2
#define NAS_PROTOCOL_DISCRIMINATOR_EMM 0x7
typedef struct _nas_header_t {
ED2(c_uint8_t security_header_type:4;,
c_uint8_t protocol_discriminator:4;)
c_uint8_t message_type;
} __attribute__ ((packed)) nas_header_t;
typedef struct _nas_security_header_t {
ED2(c_uint8_t security_header_type:4;,
c_uint8_t protocol_discriminator:4;)
c_uint32_t message_authentication_code;
c_uint8_t sequence_number;
} __attribute__ ((packed)) nas_security_header_t;
""")
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:
f.write("#define NAS_" + v_upper(k) + " " + v + "\n")
f.write("\n")
for (k, v) in sorted_msg_list:
if "ies" not in msg_list[k]:
continue;
f.write("/*******************************************************\n")
f.write(" * %s\n" % k)
f.write(" ******************************************************/\n")
for i, ie in enumerate([ies for ies in msg_list[k]["ies"] if ies["presence"] == "O"]):
f.write("#define NAS_%s_%s_PRESENT (1<<%d)\n" % (v_upper(k), v_upper(ie["value"]), i))
f.write("\n")
for i, ie in enumerate([ies for ies in msg_list[k]["ies"] if ies["presence"] == "O"]):
f.write("#define NAS_%s_%s_TYPE 0x%s\n" % (v_upper(k), v_upper(ie["value"]), re.sub('-', '0', ie["iei"])))
f.write("\n")
f.write("typedef struct _nas_%s_t {\n" % v_lower(k))
f.write(" /* Mandatory fields */\n")
optional_fields = False;
for ie in msg_list[k]["ies"]:
if ie["presence"] == "O" and optional_fields is False:
f.write("\n /* Optional fields */\n")
f.write(" c_uint32_t presencemask;\n");
optional_fields = True;
f.write(" nas_" + v_lower(ie["type"]) + "_t " + \
v_lower(ie["value"]) + ";\n")
f.write("} nas_%s_t;\n" % v_lower(k))
f.write("\n")
f.write("""typedef struct _nas_message_t {
nas_header_t h;
union {
""")
for (k, v) in sorted_msg_list:
if "ies" not in msg_list[k]:
continue;
f.write(" nas_%s_t %s;\n" % (v_lower(k), v_lower(k)))
f.write(""" };
} nas_message_t;
CORE_DECLARE(int) nas_plain_decode(nas_message_t *message, pkbuf_t *pkbuf);
CORE_DECLARE(int) nas_plain_encode(pkbuf_t **pkbuf, nas_message_t *message);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GTPV2C_MESSAGE_H__ */
""")
f.close()
f = open(outdir + 'nas_decoder2.c', 'w')
output_header_to_file(f)
f.write("""#define TRACE_MODULE _nasdec
#include "core_debug.h"
#include "nas_message2.h"
""")
for (k, v) in sorted_msg_list:
if "ies" not in msg_list[k]:
continue;
f.write("c_int32_t nas_decode_%s(nas_message_t *message, pkbuf_t *pkbuf)\n{\n" % v_lower(k))
f.write(" nas_%s_t *%s = &message->%s;\n" % (v_lower(k), v_lower(k), v_lower(k)))
f.write(" c_int32_t decoded = 0;\n")
f.write(" c_int32_t size = 0;\n\n")
for ie in [ies for ies in msg_list[k]["ies"] if ies["presence"] == "M"]:
f.write(" size = nas_decode_%s(&%s->%s, pkbuf);\n" % (v_lower(ie["type"]), v_lower(k), v_lower(ie["value"])))
f.write(" d_assert(size >= 0, return -1, \"decode failed\");\n")
f.write(" decoded += size;\n\n")
optional_fields = False;
for ie in [ies for ies in msg_list[k]["ies"] if ies["presence"] == "O"]:
if optional_fields is False:
f.write(""" while(pkbuf->len > 0)
{
c_uint8_t *buffer = pkbuf->payload;
c_uint8_t type = (*buffer) >= 0x80 ? ((*buffer) & 0xf0) : (*buffer);
size = sizeof(c_uint8_t);
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK, return -1,
"pkbuf_header error");
decoded += size;
switch(type)
{
""")
optional_fields = True;
f.write(" case NAS_%s_%s_TYPE:\n" % (v_upper(k), v_upper(ie["value"])))
f.write(" size = nas_decode_%s(&%s->%s, pkbuf);\n" % (v_lower(ie["type"]), v_lower(k), v_lower(ie["value"])))
f.write(" d_assert(size >= 0, return -1, \"decode failed\");\n")
f.write(" %s->presencemask |= NAS_%s_%s_PRESENT;\n" % (v_lower(k), v_upper(k), v_upper(ie["value"])))
f.write(" decoded += size;\n")
f.write(" break;\n")
f.write(""" default:
d_error("Unknown type(0x%x) or not implemented\\n", type);
return -1;
}
}
return decoded;
}
""")
f.write("""status_t nas_plain_decode(nas_message_t *message, pkbuf_t *pkbuf)
{
status_t rv = CORE_ERROR;
c_uint16_t size = 0;
c_uint16_t decoded = 0;
d_assert(pkbuf, return CORE_ERROR, "Null param");
d_assert(pkbuf->payload, return CORE_ERROR, "Null param");
memset(message, 0, sizeof(nas_message_t));
size = sizeof(nas_header_t);
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK,
return CORE_ERROR, "pkbuf_header error");
memcpy(&message->h, pkbuf->payload - size, size);
decoded += size;
switch(message->h.message_type)
{
""")
for (k, v) in sorted_msg_list:
if "ies" not in msg_list[k]:
continue;
f.write(" case NAS_%s:\n" % v_upper(k))
f.write(" size = nas_decode_%s(message, pkbuf);\n" % v_lower(k))
f.write(" d_assert(size >= CORE_OK, return CORE_ERROR, \"decode error\");\n")
f.write(" decoded += size;\n")
f.write(" break;\n")
f.write(""" default:
d_error("Unknown message type (0x%x) or not implemented",
message->h.message_type);
break;
}
rv = pkbuf_header(pkbuf, decoded);
d_assert(rv == CORE_OK, return CORE_ERROR, "pkbuf_header error");
return CORE_OK;
}
""")
f.close()
f = open(outdir + 'nas_encoder2.c', 'w')
output_header_to_file(f)
f.write("""#define TRACE_MODULE _nasenc
#include "core_debug.h"
#include "nas_message2.h"
""")
for (k, v) in sorted_msg_list:
if "ies" not in msg_list[k]:
continue;
f.write("c_int32_t nas_encode_%s(pkbuf_t *pkbuf, nas_message_t *message)\n{\n" % v_lower(k))
f.write(" nas_%s_t *%s = &message->%s;\n" % (v_lower(k), v_lower(k), v_lower(k)))
f.write(" c_int32_t encoded = 0;\n")
f.write(" c_int32_t size = 0;\n\n")
for ie in [ies for ies in msg_list[k]["ies"] if ies["presence"] == "M"]:
f.write(" size = nas_encode_%s(pkbuf, &%s->%s);\n" % (v_lower(ie["type"]), v_lower(k), v_lower(ie["value"])))
f.write(" d_assert(size >= 0, return -1, \"encode failed\");\n")
f.write(" encoded += size;\n\n")
for ie in [ies for ies in msg_list[k]["ies"] if ies["presence"] == "O"]:
f.write(" if (%s->presencemask & NAS_%s_%s_PRESENT)\n" % (v_lower(k), v_upper(k), v_upper(ie["value"])))
f.write(" {\n")
f.write(" size = nas_encode_optional_type(pkbuf, NAS_%s_%s_TYPE);\n" % (v_upper(k), v_upper(ie["value"])))
f.write(" d_assert(size >= 0, return encoded, \"decode failed\");\n")
f.write(" encoded += size;\n\n")
f.write(" size = nas_encode_%s(pkbuf, &%s->%s);\n" % (v_lower(ie["type"]), v_lower(k), v_lower(ie["value"])))
f.write(" d_assert(size >= 0, return encoded, \"decode failed\");\n")
f.write(" encoded += size;\n")
f.write(" }\n\n")
f.write(""" return decoded;
}
""")
f.write("""status_t nas_plain_encode(pkbuf_t **pkbuf, nas_message_t *message)
{
status_t rv = CORE_ERROR;
c_int32_t size = 0;
c_int32_t encoded = 0;
d_assert(message, return CORE_ERROR, "Null param");
/* The Packet Buffer(pkbuf_t) for NAS message MUST make a HEADROOM.
* When calculating AES_CMAC, we need to use the headroom of the packet. */
*pkbuf = pkbuf_alloc(NAS_HEADROOM, MESSAGE_SDU_SIZE);
d_assert(*pkbuf, return -1, "Null Param");
size = sizeof(nas_header_t);
rv = pkbuf_header(*pkbuf, -size);
d_assert(rv == CORE_OK, return CORE_ERROR, "pkbuf_header error");
message->h.security_header_type = 0;
memcpy((*pkbuf)->payload - size, &message->h, size);
encoded += size;
switch(message->h.message_type)
{
""")
for (k, v) in sorted_msg_list:
if "ies" not in msg_list[k]:
continue;
f.write(" case NAS_%s:\n" % v_upper(k))
f.write(" size = nas_encode_%s(*pkbuf, message);\n" % v_lower(k))
f.write(" d_assert(size >= 0, return CORE_ERROR, \"decode error\");\n")
f.write(" encoded += size;\n")
f.write(" break;\n")
f.write(""" default:
d_error("Unknown message type (0x%x) or not implemented",
message->h.message_type);
pkbuf_free((*pkbuf));
return CORE_ERROR;
}
rv = pkbuf_header(*pkbuf, encoded);
d_assert(rv == CORE_OK, return CORE_ERROR, "pkbuf_header error");
(*pkbuf)->len = encoded;
return CORE_OK;
""")
f.close()

View File

@ -143,7 +143,7 @@ static void s6a_aia_cb(void *data, struct msg **msg)
pkbuf_t *sendbuf = NULL;
event_t e;
nas_authentication_request_t *authentication_request =
&message.emm.authentication_request;
&message.authentication_request;
CHECK_SYS_DO(clock_gettime(CLOCK_REALTIME, &ts), return);

View File

@ -78,7 +78,7 @@ void ue_emm_state_operational(ue_emm_sm_t *s, event_t *e)
case NAS_ATTACH_REQUEST:
{
ue_emm_handle_attach_request(
ue, &message.emm.attach_request);
ue, &message.attach_request);
break;
}
case NAS_AUTHENTICATION_REQUEST:
@ -94,7 +94,7 @@ void ue_emm_state_operational(ue_emm_sm_t *s, event_t *e)
case NAS_AUTHENTICATION_RESPONSE:
{
ue_emm_handle_authentication_response(
ue, &message.emm.authentication_response);
ue, &message.authentication_response);
break;
}
case NAS_SECURITY_MODE_COMPLETE:
@ -206,7 +206,7 @@ static void ue_emm_handle_authentication_response(
nas_message_t message;
pkbuf_t *sendbuf = NULL;
nas_security_mode_command_t *security_mode_command =
&message.emm.security_mode_command;
&message.security_mode_command;
nas_security_algorithms_t *selected_nas_security_algorithms =
&security_mode_command->selected_nas_security_algorithms;
nas_key_set_identifier_t *nas_key_set_identifier =

View File

@ -50,7 +50,7 @@ static void nas_message_test2(abts_case *tc, void *data)
char esm_buffer[50];
nas_message_t message;
nas_attach_accept_t *attach_accept = &message.emm.attach_accept;
nas_attach_accept_t *attach_accept = &message.attach_accept;
pkbuf_t *pkbuf = NULL;
status_t rv;
@ -148,7 +148,7 @@ static void nas_message_test4(abts_case *tc, void *data)
char buffer[3];
nas_message_t message;
nas_attach_reject_t *attach_reject = &message.emm.attach_reject;
nas_attach_reject_t *attach_reject = &message.attach_reject;
pkbuf_t *pkbuf = NULL;
status_t rv;