Add support for GTP IE's from 3GPP R7
This adds support for the followng new GTP Information Elements: RAT_TYPE, USER_LOC, MS_TZ, IMEI_SV Furthermore, it allows to specify those fields as sgsnemu command line arguments.
This commit is contained in:
parent
87490d7fa9
commit
944dce3e66
17
gtp/gtp.c
17
gtp/gtp.c
|
@ -1136,6 +1136,23 @@ extern int gtp_create_context_req(struct gsn_t *gsn, struct pdp_t *pdp,
|
|||
gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_OMC_ID,
|
||||
pdp->omcid.l, pdp->omcid.v);
|
||||
|
||||
/* new R7 fields */
|
||||
if (pdp->rattype_given == 1)
|
||||
gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_RAT_TYPE,
|
||||
pdp->rattype.l, pdp->rattype.v);
|
||||
|
||||
if (pdp->userloc_given == 1)
|
||||
gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_USER_LOC,
|
||||
pdp->userloc.l, pdp->userloc.v);
|
||||
|
||||
if (pdp->mstz_given == 1)
|
||||
gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_MS_TZ,
|
||||
pdp->mstz.l, pdp->mstz.v);
|
||||
|
||||
if (pdp->imeisv_given == 1)
|
||||
gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_IMEI_SV,
|
||||
pdp->imeisv.l, pdp->imeisv.v);
|
||||
|
||||
/* TODO hisaddr0 */
|
||||
gtp_req(gsn, pdp->version, pdp, &packet, length, &pdp->hisaddr0, cbp);
|
||||
|
||||
|
|
|
@ -328,6 +328,10 @@ int gtpie_decaps(union gtpie_member* ie[], int version, void *pack, unsigned len
|
|||
case GTPIE_TRIGGER_ID:
|
||||
case GTPIE_OMC_ID:
|
||||
case GTPIE_CHARGING_ADDR:
|
||||
case GTPIE_RAT_TYPE:
|
||||
case GTPIE_USER_LOC:
|
||||
case GTPIE_MS_TZ:
|
||||
case GTPIE_IMEI_SV:
|
||||
case GTPIE_PRIVATE:
|
||||
if (j<GTPIE_SIZE) {
|
||||
ie[j] = (union gtpie_member*) p;
|
||||
|
|
|
@ -104,6 +104,10 @@ hton64(uint64_t q)
|
|||
#define GTPIE_EXT_HEADER_T 141 /* Extension Header Type List */
|
||||
#define GTPIE_TRIGGER_ID 142 /* Trigger Id */
|
||||
#define GTPIE_OMC_ID 143 /* OMC Identity */
|
||||
#define GTPIE_RAT_TYPE 151 /* Radio Access Technology Type */
|
||||
#define GTPIE_USER_LOC 152 /* User Location Information */
|
||||
#define GTPIE_MS_TZ 153 /* MS Time Zone */
|
||||
#define GTPIE_IMEI_SV 154 /* IMEI Software Version */
|
||||
/* 239-250 Reserved for the GPRS charging protocol (see GTP' in GSM 12.15) */
|
||||
#define GTPIE_CHARGING_ADDR 251 /* Charging Gateway Address */
|
||||
/* 252-254 Reserved for the GPRS charging protocol (see GTP' in GSM 12.15) */
|
||||
|
|
|
@ -188,6 +188,14 @@ struct pdp_t {
|
|||
struct ul255_t pco_req; /* Requested packet control options. */
|
||||
struct ul255_t pco_neg; /* Negotiated packet control options. */
|
||||
uint32_t selmode; /* Selection mode. */
|
||||
struct ul255_t rattype; /* Radio Access Technology Type */
|
||||
int rattype_given; /* Radio Access Technology Type given*/
|
||||
struct ul255_t userloc; /* User Location Information */
|
||||
int userloc_given; /* User Location Information given*/
|
||||
struct ul255_t mstz; /* MS Time Zone */
|
||||
int mstz_given; /* MS Time Zone given*/
|
||||
struct ul255_t imeisv; /* IMEI Software Version */
|
||||
int imeisv_given; /* IMEI Software Version given*/
|
||||
|
||||
/* Additional parameters used by library */
|
||||
|
||||
|
|
|
@ -40,6 +40,10 @@ const char *gengetopt_args_info_help[] = {
|
|||
" --gtpversion=INT GTP version to use (default=`1')",
|
||||
" -a, --apn=STRING Access point name (default=`internet')",
|
||||
" --selmode=INT Selection mode (default=`0x01')",
|
||||
" --rattype=INT Radio Access Technology Type (optional-1to5)",
|
||||
" --userloc=STRING User Location Information (optional-type.MCC.MNC.LAC.CIorSACorRAC)",
|
||||
" --mstz=STRING MS Time Zone (optional- sign.NbQuartersOfAnHour.DSTAdjustment)",
|
||||
" --imeisv=STRING IMEI(SV) International Mobile Equipment Identity (and Software Version) (optional,16 digits)",
|
||||
" -i, --imsi=STRING IMSI (default=`240010123456789')",
|
||||
" --nsapi=INT NSAPI (default=`0')",
|
||||
" -m, --msisdn=STRING Mobile Station ISDN number (default=`46702123456')",
|
||||
|
@ -113,6 +117,10 @@ void clear_given (struct gengetopt_args_info *args_info)
|
|||
args_info->gtpversion_given = 0 ;
|
||||
args_info->apn_given = 0 ;
|
||||
args_info->selmode_given = 0 ;
|
||||
args_info->rattype_given = 0 ;
|
||||
args_info->userloc_given = 0 ;
|
||||
args_info->mstz_given = 0 ;
|
||||
args_info->imeisv_given = 0 ;
|
||||
args_info->imsi_given = 0 ;
|
||||
args_info->nsapi_given = 0 ;
|
||||
args_info->msisdn_given = 0 ;
|
||||
|
@ -158,6 +166,14 @@ void clear_args (struct gengetopt_args_info *args_info)
|
|||
args_info->apn_orig = NULL;
|
||||
args_info->selmode_arg = 0x01;
|
||||
args_info->selmode_orig = NULL;
|
||||
args_info->rattype_arg = "1";
|
||||
args_info->rattype_orig = NULL;
|
||||
args_info->userloc_arg = strdup("02509946241207");
|
||||
args_info->userloc_orig = NULL;
|
||||
args_info->mstz_arg = strdup("0");
|
||||
args_info->mstz_orig = NULL;
|
||||
args_info->imeisv_arg = strdup("2143658709214365");
|
||||
args_info->imeisv_orig = NULL;
|
||||
args_info->imsi_arg = gengetopt_strdup ("240010123456789");
|
||||
args_info->imsi_orig = NULL;
|
||||
args_info->nsapi_arg = 0;
|
||||
|
@ -768,6 +784,10 @@ cmdline_parser_internal (int argc, char * const *argv, struct gengetopt_args_inf
|
|||
{ "gtpversion", 1, NULL, 0 },
|
||||
{ "apn", 1, NULL, 'a' },
|
||||
{ "selmode", 1, NULL, 0 },
|
||||
{ "rattype", 1, NULL, 0},
|
||||
{ "userloc", 1, NULL, 0},
|
||||
{ "mstz", 1, NULL, 0},
|
||||
{ "imeisv", 1, NULL, 0},
|
||||
{ "imsi", 1, NULL, 'i' },
|
||||
{ "nsapi", 1, NULL, 0 },
|
||||
{ "msisdn", 1, NULL, 'm' },
|
||||
|
@ -1143,6 +1163,55 @@ cmdline_parser_internal (int argc, char * const *argv, struct gengetopt_args_inf
|
|||
free (args_info->selmode_orig); /* free previous string */
|
||||
args_info->selmode_orig = gengetopt_strdup (optarg);
|
||||
}
|
||||
/* Radio Access Technology Type. */
|
||||
else if (strcmp (long_options[option_index].name, "rattype") == 0)
|
||||
{
|
||||
if (args_info->rattype_given)
|
||||
{
|
||||
fprintf (stderr, "%s: `--rattype' option given more than once\n", PACKAGE);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
args_info->rattype_given = 1;
|
||||
/* args_info->rattype_arg = strtol (optarg,&stop_char,0); */
|
||||
args_info->rattype_arg = strdup (optarg);
|
||||
break;
|
||||
}
|
||||
/* User Location Information. */
|
||||
else if (strcmp (long_options[option_index].name, "userloc") == 0)
|
||||
{
|
||||
if (args_info->userloc_given)
|
||||
{
|
||||
fprintf (stderr, "%s: `--userloc' option given more than once\n", PACKAGE);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
args_info->userloc_given = 1;
|
||||
args_info->userloc_arg = strdup (optarg);
|
||||
break;
|
||||
}
|
||||
/* MS Time Zone */
|
||||
else if (strcmp (long_options[option_index].name, "mstz") == 0)
|
||||
{
|
||||
if (args_info->mstz_given)
|
||||
{
|
||||
fprintf (stderr, "%s: `--mstz' option given more than once\n", PACKAGE);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
args_info->mstz_given = 1;
|
||||
args_info->mstz_arg = strdup (optarg);
|
||||
break;
|
||||
}
|
||||
/* IMEI(SV) */
|
||||
else if (strcmp (long_options[option_index].name, "imeisv") == 0)
|
||||
{
|
||||
if (args_info->imeisv_given)
|
||||
{
|
||||
fprintf (stderr, "%s: `--imeisv' option given more than once\n", PACKAGE);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
args_info->imeisv_given = 1;
|
||||
args_info->imeisv_arg = strdup (optarg);
|
||||
break;
|
||||
}
|
||||
/* NSAPI. */
|
||||
else if (strcmp (long_options[option_index].name, "nsapi") == 0)
|
||||
{
|
||||
|
|
|
@ -61,6 +61,18 @@ struct gengetopt_args_info
|
|||
int selmode_arg; /* Selection mode (default='0x01'). */
|
||||
char * selmode_orig; /* Selection mode original value given at command line. */
|
||||
const char *selmode_help; /* Selection mode help description. */
|
||||
char * rattype_arg; /* Radio Access Technology Type (optional). */
|
||||
char * rattype_orig;
|
||||
char * rattype_help;
|
||||
char * userloc_arg; /* User Location Information (optional). */
|
||||
char * userloc_orig;
|
||||
char * userloc_help;
|
||||
char * mstz_arg; /* MS Time Zone (optional). */
|
||||
char * mstz_orig;
|
||||
char * mstz_help;
|
||||
char * imeisv_arg; /* IMEI(SV) (optional). */
|
||||
char * imeisv_orig;
|
||||
char * imeisv_help;
|
||||
char * imsi_arg; /* IMSI (default='240010123456789'). */
|
||||
char * imsi_orig; /* IMSI original value given at command line. */
|
||||
const char *imsi_help; /* IMSI help description. */
|
||||
|
@ -124,6 +136,10 @@ struct gengetopt_args_info
|
|||
int gtpversion_given ; /* Whether gtpversion was given. */
|
||||
int apn_given ; /* Whether apn was given. */
|
||||
int selmode_given ; /* Whether selmode was given. */
|
||||
int rattype_given ; /* Whether rattype was given. */
|
||||
int userloc_given ; /* Whether userloc was given. */
|
||||
int mstz_given ; /* Whether mstz was given. */
|
||||
int imeisv_given ; /* Whether imeisv was given. */
|
||||
int imsi_given ; /* Whether imsi was given. */
|
||||
int nsapi_given ; /* Whether nsapi was given. */
|
||||
int msisdn_given ; /* Whether msisdn was given. */
|
||||
|
|
|
@ -104,6 +104,14 @@ struct {
|
|||
uint16_t cch;
|
||||
struct ul255_t apn;
|
||||
uint8_t selmode;
|
||||
struct ul255_t rattype;
|
||||
int rattype_given;
|
||||
struct ul255_t userloc;
|
||||
int userloc_given;
|
||||
struct ul255_t mstz;
|
||||
int mstz_given;
|
||||
struct ul255_t imeisv;
|
||||
int imeisv_given;
|
||||
struct ul16_t msisdn;
|
||||
} options;
|
||||
|
||||
|
@ -211,6 +219,23 @@ int process_options(int argc, char **argv) {
|
|||
|
||||
struct hostent *host;
|
||||
unsigned int n;
|
||||
uint16_t i;
|
||||
uint8_t a;
|
||||
uint8_t b;
|
||||
char * tmp;
|
||||
char * pch;
|
||||
char * type;
|
||||
char * mcc;
|
||||
char * mnc;
|
||||
char * lac;
|
||||
int lac_d;
|
||||
char * rest;
|
||||
char *userloc_el[] = {"TYPE","MCC","MNC","LAC","REST"};
|
||||
char *mstz_el[] = {"SIGN","QUARTERS","DST"};
|
||||
int sign ;
|
||||
int nbquarters ;
|
||||
int DST ;
|
||||
|
||||
|
||||
if (cmdline_parser (argc, argv, &args_info) != 0)
|
||||
return -1;
|
||||
|
@ -449,6 +474,174 @@ int process_options(int argc, char **argv) {
|
|||
options.selmode = args_info.selmode_arg;
|
||||
printf("Using selection mode: %d\n", args_info.selmode_arg);
|
||||
|
||||
/* rattype */
|
||||
if (args_info.rattype_given == 1 ) {
|
||||
options.rattype_given = 1 ;
|
||||
options.rattype.l = strlen(args_info.rattype_arg) ;
|
||||
options.rattype.v[0] = atoi(args_info.rattype_arg) ;
|
||||
printf("Using RAT Type: %s\n", args_info.rattype_arg);
|
||||
}
|
||||
|
||||
/* userloc */
|
||||
if (args_info.userloc_given == 1 ) {
|
||||
printf("Using User Location Information: %s\n", args_info.userloc_arg);
|
||||
tmp = args_info.userloc_arg ;
|
||||
n=0;
|
||||
pch = strtok (tmp,".");
|
||||
while (pch != NULL) {
|
||||
userloc_el[n] = pch ;
|
||||
pch = strtok (NULL, ".");
|
||||
n++;
|
||||
}
|
||||
|
||||
options.userloc_given = 1 ;
|
||||
options.userloc.l = 8 ;
|
||||
|
||||
/* 3GPP Geographic Location Type t0 / t1 / t2 */
|
||||
type = userloc_el[0];
|
||||
printf("->type : %c\n", type[0]);
|
||||
if ( (strlen(type)!=1) || (!isdigit(type[0])) ) {
|
||||
printf("Invalid type \n");
|
||||
return -1;
|
||||
}
|
||||
/* options.userloc.v[0] = 0x00 */
|
||||
options.userloc.v[0] = type[0] - 48;
|
||||
|
||||
/* MCC */
|
||||
mcc = userloc_el[1] ;
|
||||
printf("->mcc : %s\n", mcc);
|
||||
if (strlen(mcc)!=3) {
|
||||
printf("Invalid MCC lenght\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* MNC */
|
||||
mnc = userloc_el[2] ;
|
||||
printf("->mnc : %s\n", mnc);
|
||||
|
||||
/* octet 5 - MCC Digit 2 - MCC Digit 1 */
|
||||
/* options.userloc.v[1] = 0x52 */
|
||||
a = (uint8_t) (mcc[0] - 48);
|
||||
b = (uint8_t) (mcc[1] - 48);
|
||||
options.userloc.v[1] = 16*b+a ;
|
||||
|
||||
/* octet 6 - MNC Digit 3 - MCC Digit 3 */
|
||||
/* options.userloc.v[2] = 0xf0 */
|
||||
a = (uint8_t) (mcc[2] - 48);
|
||||
|
||||
if ( (strlen(mnc) > 3) || (strlen(mnc) < 2)) {
|
||||
printf("Invalid MNC lenght\n");
|
||||
return -1;
|
||||
}
|
||||
if (strlen(mnc)==2) {
|
||||
b = 15 ;
|
||||
}
|
||||
if (strlen(mnc)==3) {
|
||||
b = (uint8_t) (mnc[2] - 48);
|
||||
}
|
||||
options.userloc.v[2] = 16*b+a ;
|
||||
|
||||
/* octet 7 - MNC Digit 2 - MNC Digit 1 */
|
||||
/* options.userloc.v[3] = 0x99*/
|
||||
a = (uint8_t) (mnc[0]- 48);
|
||||
b = (uint8_t) (mnc[1]- 48);
|
||||
options.userloc.v[3] = 16*b+a ;
|
||||
|
||||
/* LAC */
|
||||
lac = userloc_el[3] ;
|
||||
/*options.userloc.v[4] = 0x12 ; */
|
||||
/*options.userloc.v[5] = 0x10 ; */
|
||||
printf("->LAC: %s\n", lac);
|
||||
lac_d = atoi(lac);
|
||||
if (lac_d>65535 || lac_d<1) {
|
||||
printf("Invalid LAC\n");
|
||||
return -1;
|
||||
}
|
||||
i = lac_d >> 8 ;
|
||||
options.userloc.v[4] = i; /* octet 8 - LAC */
|
||||
options.userloc.v[5] = lac_d; /* octet 9 - LAC */
|
||||
|
||||
/* CI/SAC/RAC */
|
||||
rest = userloc_el[4] ;
|
||||
printf("->CI/SAC/RAC : %s\n", rest);
|
||||
lac_d = atoi(rest);
|
||||
if (lac_d>65535 || lac_d<1) {
|
||||
printf("Invalid CI/SAC/RAC\n");
|
||||
return -1;
|
||||
}
|
||||
/*options.userloc.v[6] = 0x04 ; */
|
||||
/*options.userloc.v[7] = 0xb7 ; */
|
||||
i = lac_d >> 8 ;
|
||||
options.userloc.v[6] = i; /* octet 10 - t0,CI / t1,SAC / t2,RAC */
|
||||
options.userloc.v[7] = lac_d; /* octet 11 - t0,CI / t1,SAC / t2,RAC */
|
||||
}
|
||||
/* mstz */
|
||||
if (args_info.mstz_given == 1 ) {
|
||||
options.mstz_given = 1 ;
|
||||
options.mstz.l = 2 ;
|
||||
|
||||
printf("Using MS Time Zone: %s\n", args_info.mstz_arg);
|
||||
tmp = args_info.mstz_arg ;
|
||||
n=0;
|
||||
pch = strtok (tmp,".");
|
||||
while (pch != NULL) {
|
||||
mstz_el[n] = pch ;
|
||||
pch = strtok (NULL, ".");
|
||||
n++;
|
||||
}
|
||||
|
||||
/* sign */
|
||||
sign = atoi(mstz_el[0]) ;
|
||||
printf("->Sign (0=+ / 1=-): %d\n", sign);
|
||||
if ( sign!=0 && sign!=1 ) {
|
||||
printf("Invalid Sign \n");
|
||||
return -1;
|
||||
}
|
||||
/* nbquarters */
|
||||
nbquarters = atoi(mstz_el[1]) ;
|
||||
printf("->Number of Quarters of an Hour : %d\n", nbquarters);
|
||||
if ( nbquarters<0 || nbquarters>79 ) {
|
||||
printf("Invalid Number of Quarters \n");
|
||||
return -1;
|
||||
}
|
||||
/* DST */
|
||||
DST = atoi(mstz_el[2]) ;
|
||||
printf("->Daylight Saving Time Adjustment : %d\n", DST);
|
||||
if ( DST<0 || DST>3 ) {
|
||||
printf("Invalid DST Adjustment \n");
|
||||
return -1;
|
||||
}
|
||||
/* 12345678
|
||||
bits 123 = unit of # of quarters of an hour
|
||||
bits 678 = # of quarters of an hour / 10
|
||||
bit 5 = sign
|
||||
*/
|
||||
i= nbquarters % 10 ;
|
||||
i = i << 4 ;
|
||||
i = i + nbquarters / 10 + 8 * sign;
|
||||
/* options.mstz.v[0] = 0x69 ; */
|
||||
/* options.mstz.v[1] = 0x01 ; */
|
||||
options.mstz.v[0] = i ;
|
||||
options.mstz.v[1] = DST ;
|
||||
n = (i & 0x08) ? '-' : '+';
|
||||
printf("->Human Readable MS Time Zone : GMT %c %d hours %d minutes\n", n , nbquarters / 4, nbquarters % 4 * 15);
|
||||
}
|
||||
|
||||
/* imeisv */
|
||||
if (args_info.imeisv_given == 1 ) {
|
||||
options.imeisv_given = 1 ;
|
||||
if (strlen(args_info.imeisv_arg)!=16) {
|
||||
printf("Invalid IMEI(SV)\n");
|
||||
return -1;
|
||||
}
|
||||
options.imeisv.l = 8 ;
|
||||
for(n=0; n<8; n++) {
|
||||
a = (uint8_t) (args_info.imeisv_arg [2*n] - 48) ;
|
||||
b = (uint8_t) (args_info.imeisv_arg [2*n + 1] - 48) ;
|
||||
options.imeisv.v[n] = 16*b+a ;
|
||||
}
|
||||
printf("Using IMEI(SV): %s\n", args_info.imeisv_arg);
|
||||
}
|
||||
|
||||
/* msisdn */
|
||||
if (strlen(args_info.msisdn_arg)>(sizeof(options.msisdn.v)-1)) {
|
||||
|
@ -1138,6 +1331,22 @@ int main(int argc, char **argv)
|
|||
|
||||
pdp->selmode = options.selmode;
|
||||
|
||||
pdp->rattype.l = options.rattype.l;
|
||||
memcpy(pdp->rattype.v, options.rattype.v, options.rattype.l);
|
||||
pdp->rattype_given = options.rattype_given;
|
||||
|
||||
pdp->userloc.l = options.userloc.l;
|
||||
memcpy(pdp->userloc.v, options.userloc.v, options.userloc.l);
|
||||
pdp->userloc_given = options.userloc_given;
|
||||
|
||||
pdp->mstz.l = options.mstz.l;
|
||||
memcpy(pdp->mstz.v, options.mstz.v, options.mstz.l);
|
||||
pdp->mstz_given = options.mstz_given;
|
||||
|
||||
pdp->imeisv.l = options.imeisv.l;
|
||||
memcpy(pdp->imeisv.v, options.imeisv.v, options.imeisv.l);
|
||||
pdp->imeisv_given = options.imeisv_given;
|
||||
|
||||
if (options.apn.l > sizeof(pdp->apn_use.v)) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0, "APN length too big");
|
||||
exit(1);
|
||||
|
|
Reference in New Issue