Harald Welte | 379d45a | 2017-08-03 09:55:15 +0200 | [diff] [blame] | 1 | module GGSN_Tests { |
| 2 | |
Harald Welte | 94ade36 | 2017-08-04 00:36:55 +0200 | [diff] [blame] | 3 | import from General_Types all; |
| 4 | import from IPL4asp_PortType all; |
| 5 | import from IPL4asp_Types all; |
| 6 | import from GTP_CodecPort all; |
| 7 | import from GTP_CodecPort_CtrlFunct all; |
| 8 | import from GTPC_Types all; |
| 9 | import from GTPU_Types all; |
| 10 | |
| 11 | const integer GTP0_PORT := 3386; |
| 12 | const integer GTP1C_PORT := 2123; |
| 13 | const integer GTP1U_PORT := 2152; |
Harald Welte | 876345e | 2017-08-04 16:19:59 +0200 | [diff] [blame] | 14 | const charstring g_bind_ip_c := "127.23.42.1"; |
| 15 | const charstring g_bind_ip_u := g_bind_ip_c; |
Harald Welte | 94ade36 | 2017-08-04 00:36:55 +0200 | [diff] [blame] | 16 | |
| 17 | type component GT_CT { |
| 18 | port GTPC_PT GTPC; |
| 19 | port GTPU_PT GTPU; |
| 20 | |
| 21 | var OCT1 g_restart_ctr := '01'O; |
| 22 | /* FIXME: unify with g_bind_ip + parse from config file */ |
Harald Welte | 876345e | 2017-08-04 16:19:59 +0200 | [diff] [blame] | 23 | var OCT4 g_sgsn_ip_c := '7f172a01'O; |
| 24 | var OCT4 g_sgsn_ip_u := '7f172a01'O; |
Harald Welte | 94ade36 | 2017-08-04 00:36:55 +0200 | [diff] [blame] | 25 | /* FIXME: parse remName from config file */ |
| 26 | var GtpPeer g_peer := { connId := 0, remName := "127.0.0.6", remPort := GTP1C_PORT }; |
| 27 | timer T_default := 3.0; |
| 28 | } |
| 29 | |
| 30 | function f_init() runs on GT_CT { |
| 31 | var Result res; |
| 32 | map(self:GTPC, system:GTPC); |
Harald Welte | 876345e | 2017-08-04 16:19:59 +0200 | [diff] [blame] | 33 | res := GTP_CodecPort_CtrlFunct.f_IPL4_listen(GTPC, g_bind_ip_c, GTP1C_PORT, {udp:={}}); |
Harald Welte | 94ade36 | 2017-08-04 00:36:55 +0200 | [diff] [blame] | 34 | log("GTP1C ConnectionID: ", res.connId); |
| 35 | g_peer.connId := res.connId; |
| 36 | |
| 37 | map(self:GTPU, system:GTPU); |
Harald Welte | 876345e | 2017-08-04 16:19:59 +0200 | [diff] [blame] | 38 | GTP_CodecPort_CtrlFunct.f_GTPU_listen(GTPU, g_bind_ip_u, GTP1U_PORT, {udp:={}}); |
Harald Welte | 94ade36 | 2017-08-04 00:36:55 +0200 | [diff] [blame] | 39 | } |
| 40 | |
| 41 | /* generalized GTP-C receive template */ |
| 42 | template PDU_GTPC tr_GTP1C_PDU(template OCT1 msg_type, template OCT4 teid) := { |
| 43 | /* N-PDU Number flag (PN) shall be set to '0'. A GTP-C receiver shall not return an |
| 44 | * error if this flag is set to '1'. */ |
| 45 | pn_bit := '0'B, |
| 46 | /* Sequence number flag (S) shall be set to '1'. */ |
| 47 | s_bit := '1'B, |
| 48 | e_bit := ?, |
| 49 | spare := ?, |
| 50 | /* Protocol Type flag (PT) shall be set to '1'.*/ |
| 51 | pt := '1'B, |
| 52 | /* Version shall be set to decimal 1 ('001'). */ |
| 53 | version := '001'B, |
| 54 | messageType := msg_type, |
| 55 | lengthf := ?, |
| 56 | teid := teid, |
| 57 | opt_part := *, |
| 58 | gtpc_pdu := ? |
| 59 | } |
| 60 | |
| 61 | /* generalized GTP-C send template */ |
| 62 | template PDU_GTPC ts_GTP1C_PDU(OCT1 msg_type, OCT4 teid, GTPC_PDUs pdu) := { |
| 63 | /* N-PDU Number flag (PN) shall be set to '0'. A GTP-C receiver shall not return an |
| 64 | * error if this flag is set to '1'. */ |
| 65 | pn_bit := '0'B, |
| 66 | /* Sequence number flag (S) shall be set to '1'. */ |
| 67 | s_bit := '1'B, |
| 68 | e_bit := '0'B, |
| 69 | spare := '0'B, |
| 70 | /* Protocol Type flag (PT) shall be set to '1'.*/ |
| 71 | pt := '1'B, |
| 72 | /* Version shall be set to decimal 1 ('001'). */ |
| 73 | version := '001'B, |
| 74 | messageType := msg_type, |
| 75 | lengthf := 0, /* we assume encoder overwrites this */ |
| 76 | teid := teid, |
| 77 | opt_part := { |
| 78 | sequenceNumber := '9801'O, |
| 79 | npduNumber := '00'O, |
| 80 | nextExtHeader := '00'O, |
| 81 | gTPC_extensionHeader_List := omit |
| 82 | }, |
| 83 | gtpc_pdu := pdu |
| 84 | } |
| 85 | |
| 86 | /* recovery IE */ |
| 87 | template Recovery_gtpc ts_Recovery(OCT1 restart_counter) := { |
| 88 | type_gtpc := '00'O, /* we assume encoder fixes this */ |
| 89 | restartCounter := restart_counter |
| 90 | } |
| 91 | |
| 92 | /* template matching reception of GTP-C echo-request */ |
| 93 | template Gtp1cUnitdata tr_GTPC_MsgType(template GtpPeer peer, template OCT1 msg_type, template OCT4 teid) := { |
| 94 | peer := peer, |
| 95 | gtpc := tr_GTP1C_PDU(msg_type, teid) |
| 96 | } |
| 97 | |
| 98 | /* template matching reception of GTP-C echo-request */ |
| 99 | template Gtp1cUnitdata tr_GTPC_PING(template GtpPeer peer) := tr_GTPC_MsgType(peer, echoRequest, '00000000'O); |
| 100 | |
| 101 | template GTPC_PDUs ts_EchoRespPDU(OCT1 restart_counter) := { |
| 102 | echoResponse := { |
| 103 | recovery := { |
| 104 | type_gtpc := '00'O, /* we assume encoder fixes? */ |
| 105 | restartCounter := restart_counter |
| 106 | }, |
| 107 | private_extension_gtpc := omit |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | /* master template for senidng a GTP-C echo response */ |
| 112 | template Gtp1cUnitdata ts_GTPC_PONG(GtpPeer peer, OCT1 rest_ctr) := { |
| 113 | peer := peer, |
| 114 | gtpc := ts_GTP1C_PDU(echoResponse, '00000000'O, valueof(ts_EchoRespPDU(rest_ctr))) |
| 115 | } |
| 116 | |
| 117 | template EndUserAddress t_EuaIPv4(template OCT4 ip_addr) := { |
| 118 | type_gtpc := '80'O, |
| 119 | endUserAddress := { |
| 120 | endUserAddressIPv4 := { |
| 121 | lengthf := 2, |
| 122 | pdp_typeorg := '0001'B, |
| 123 | spare := '1111'B, |
| 124 | pdp_typenum := '21'O, |
| 125 | ipv4_address := ip_addr |
| 126 | } |
| 127 | } |
| 128 | } |
| 129 | template EndUserAddress t_EuaIPv4Dyn := t_EuaIPv4(omit); |
| 130 | template EndUserAddress t_EuaIPv6(template OCT16 ip_addr) := { |
| 131 | type_gtpc := '80'O, |
| 132 | endUserAddress := { |
| 133 | endUserAddressIPv6 := { |
| 134 | lengthf := 2, |
| 135 | pdp_typeorg := '0001'B, |
| 136 | spare := '1111'B, |
| 137 | pdp_typenum := '57'O, |
| 138 | ipv6_address := ip_addr |
| 139 | } |
| 140 | } |
| 141 | } |
| 142 | template EndUserAddress t_EuaIPv6Dyn := t_EuaIPv6(omit); |
| 143 | |
| 144 | template AccessPointName ts_APN(octetstring apn) := { |
| 145 | type_gtpc := '83'O, |
| 146 | lengthf := lengthof(apn), |
| 147 | apn_value := apn |
| 148 | } |
| 149 | |
| 150 | template GSN_Address_GTPC ts_GsnAddr(octetstring ip_addr) := { |
| 151 | type_gtpc := '85'O, |
| 152 | lengthf := lengthof(ip_addr), |
| 153 | addressf := ip_addr |
| 154 | } |
| 155 | |
| 156 | template MSISDN ts_Msisdn(octetstring msisdn) := { |
| 157 | type_gtpc := '86'O, |
| 158 | lengthf := lengthof(msisdn), |
| 159 | msisdn := msisdn |
| 160 | } |
| 161 | |
| 162 | template QualityOfServiceProfile ts_QosDefault := { |
| 163 | type_gtpc := '87'O, |
| 164 | lengthf := 4, |
| 165 | allocRetensionPrio := '00'O, |
| 166 | qos_ProfileValue := { |
| 167 | reliabilityClass := '011'B, |
| 168 | delayClass := '001'B, |
| 169 | spare1 := '00'B, |
| 170 | precedenceClass := '010'B, |
| 171 | spare2 := '0'B, |
| 172 | peakThroughput := '1001'B, |
| 173 | meanThroughput := '11111'B, |
| 174 | spare3 := '000'B, |
| 175 | deliverErroneusSDU := omit, |
| 176 | deliveryOrder := omit, |
| 177 | trafficClass := omit, |
| 178 | maxSDUSize := omit, |
| 179 | maxBitrateUplink := omit, |
| 180 | maxBitrateDownlink := omit, |
| 181 | sduErrorRatio := omit, |
| 182 | residualBER := omit, |
| 183 | trafficHandlingPriority := omit, |
| 184 | transferDelay := omit, |
| 185 | guaranteedBitRateUplink := omit, |
| 186 | guaranteedBitRateDownlink := omit, |
| 187 | sourceStatisticsDescriptor := omit, |
| 188 | signallingIndication := omit, |
| 189 | spare4 := omit, |
| 190 | maxBitrateDownlinkExt := omit, |
| 191 | guaranteedBitRateDownlinkExt := omit, |
| 192 | maxBitrateUplinkExt := omit, |
| 193 | guaranteedBitRateUplinkExt := omit |
| 194 | } |
| 195 | } |
| 196 | |
| 197 | template IMSI_gtpc ts_Imsi(hexstring digits) := { |
| 198 | type_gtpc := '02'O, |
| 199 | digits := digits, |
| 200 | padding := 'F'H |
| 201 | } |
| 202 | |
| 203 | template GTPC_PDUs ts_CreatePdpPDU(hexstring imsi, OCT1 restart_ctr, OCT4 teid_data, OCT4 teid_ctrl, |
| 204 | BIT4 nsapi, EndUserAddress eua, octetstring apn, |
| 205 | octetstring sgsn_ip_sign, octetstring sgsn_ip_data, |
| 206 | octetstring msisdn) := { |
| 207 | createPDPContextRequest := { |
| 208 | imsi := ts_Imsi(imsi), |
| 209 | rai := omit, |
| 210 | recovery := ts_Recovery(restart_ctr), |
| 211 | selectionMode := { |
| 212 | type_gtpc := '0F'O, |
| 213 | selectModeValue := '00'B, |
| 214 | spare := '111111'B |
| 215 | }, |
| 216 | teidDataI := { |
| 217 | type_gtpc := '00'O, |
| 218 | teidDataI := teid_data |
| 219 | }, |
| 220 | teidControlPlane := { |
| 221 | type_gtpc := '00'O, |
| 222 | teidControlPlane := teid_ctrl |
| 223 | }, |
| 224 | nsapi := { |
| 225 | type_gtpc := '00'O, |
| 226 | nsapi := nsapi, |
| 227 | unused := '0000'B |
| 228 | }, |
| 229 | linked_nsapi := omit, |
| 230 | charging_char := omit, |
| 231 | trace_ref := omit, |
| 232 | trace_type := omit, |
| 233 | endUserAddress := eua, |
| 234 | accessPointName := ts_APN(apn), |
| 235 | protConfigOptions := omit, |
| 236 | sgsn_addr_signalling := ts_GsnAddr(sgsn_ip_sign), |
| 237 | sgsn_addr_traffic := ts_GsnAddr(sgsn_ip_data), |
| 238 | msisdn := ts_Msisdn(msisdn), |
| 239 | qualityOfServiceProfile := ts_QosDefault, |
| 240 | tft := omit, |
| 241 | triggerId := omit, |
| 242 | omcId := omit, |
| 243 | commonFlags := omit, |
| 244 | aPN_Restriction := omit, |
| 245 | ratType := omit, |
| 246 | userLocationInformation := omit, |
| 247 | mS_TimeZone := omit, |
| 248 | imeisv := omit, |
| 249 | camelChargingInformationContainer := omit, |
| 250 | additionalTraceInfo := omit, |
| 251 | correlationID := omit, |
| 252 | evolvedAllocationRetentionPriorityI := omit, |
| 253 | extendedCommonFlags := omit, |
| 254 | userCSGInformation := omit, |
| 255 | aPN_AMBR := omit, |
| 256 | signallingPriorityIndication := omit, |
| 257 | cN_OperatorSelectionEntity := omit, |
| 258 | private_extension_gtpc := omit |
| 259 | } |
| 260 | } |
| 261 | |
| 262 | template Gtp1cUnitdata ts_GTPC_CreatePDP(GtpPeer peer, hexstring imsi, OCT1 restart_ctr, OCT4 teid_data, |
| 263 | OCT4 teid_ctrl, BIT4 nsapi, EndUserAddress eua, |
| 264 | octetstring apn, octetstring sgsn_ip_sign, |
| 265 | octetstring sgsn_ip_data, octetstring msisdn) := { |
| 266 | peer := peer, |
| 267 | gtpc := ts_GTP1C_PDU(createPDPContextRequest, '00000000'O, |
| 268 | valueof(ts_CreatePdpPDU(imsi, restart_ctr, teid_data, teid_ctrl, |
| 269 | nsapi, eua, apn, sgsn_ip_sign, |
| 270 | sgsn_ip_data, msisdn))) |
| 271 | } |
| 272 | |
Harald Welte | 3af8948 | 2017-08-04 16:20:23 +0200 | [diff] [blame^] | 273 | /* GTP-U */ |
| 274 | |
| 275 | template PDU_GTPU tr_GTP1U_PDU(template OCT1 msg_type, template OCT4 teid) := { |
| 276 | pn_bit := ?, |
| 277 | s_bit := ?, |
| 278 | e_bit := ?, |
| 279 | spare := ?, |
| 280 | /* Protocol Type flag (PT) shall be set to '1' in GTP */ |
| 281 | pt := '1'B, |
| 282 | /* Version shall be set to decimal 1 ('001'). */ |
| 283 | version := '001'B, |
| 284 | messageType := msg_type, |
| 285 | lengthf := ?, |
| 286 | teid := teid, |
| 287 | opt_part := *, |
| 288 | gtpu_IEs := ? |
| 289 | } |
| 290 | |
| 291 | /* generalized GTP-U send template */ |
| 292 | template PDU_GTPU ts_GTP1U_PDU(OCT1 msg_type, OCT4 teid, GTPU_IEs ies, |
| 293 | template GTPU_Header_optional_part opt := omit) := { |
| 294 | /* N-PDU Number flag (PN): the GTP-U header contains a meaningful N-PDU Number field if the PN |
| 295 | * flag is set to 1. */ |
| 296 | pn_bit := '0'B, /* we assume the encoder overwrites this if an optional part is given */ |
| 297 | /* If the Sequence Number flag (S) is set to '1' the sequence number field is present and |
| 298 | * meaningful otherwise it is set to '0'. For GTP-U messages Echo Request, Echo Response, |
| 299 | * Error Indication and Supported Extension Headers Notification, the S flag shall be set to '1'. */ |
| 300 | s_bit := '0'B, /* we assume the encoder overwrites this if an optional part is given */ |
| 301 | /* Extension header presence */ |
| 302 | e_bit := '0'B, |
| 303 | spare := '0'B, |
| 304 | /* Protocol Type flag (PT) shall be set to '1' in GTP */ |
| 305 | pt := '1'B, |
| 306 | /* Version shall be set to decimal 1 ('001'). */ |
| 307 | version := '001'B, |
| 308 | messageType := msg_type, |
| 309 | lengthf := 0, /* we assume encoder overwrites this */ |
| 310 | teid := teid, |
| 311 | opt_part := opt, |
| 312 | gtpu_IEs := ies |
| 313 | } |
| 314 | |
| 315 | template Gtp1uUnitdata tr_GTPU_MsgType(template GtpPeer peer, template OCT1 msg_type, template OCT4 teid) := { |
| 316 | peer := peer, |
| 317 | gtpu := tr_GTP1U_PDU(msg_type, teid) |
| 318 | } |
| 319 | |
| 320 | |
| 321 | /* template matching reception of GTP-C echo-request */ |
| 322 | template Gtp1uUnitdata tr_GTPU_PING(template GtpPeer peer) := tr_GTPU_MsgType(peer, echoRequest, '00000000'O); |
| 323 | |
| 324 | template GTPU_IEs ts_UEchoRespPDU(OCT1 restart_counter) := { |
| 325 | echoResponse_IEs := { |
| 326 | recovery_gtpu := { |
| 327 | type_gtpu := '00'O, /* we assume encoder fixes? */ |
| 328 | restartCounter := restart_counter |
| 329 | }, |
| 330 | private_extension_gtpu := omit |
| 331 | } |
| 332 | } |
| 333 | |
| 334 | /* master template for sending a GTP-U echo response */ |
| 335 | template Gtp1uUnitdata ts_GTPU_PONG(GtpPeer peer, OCT1 rest_ctr) := { |
| 336 | peer := peer, |
| 337 | gtpu := ts_GTP1U_PDU(echoResponse, '00000000'O, valueof(ts_UEchoRespPDU(rest_ctr))) |
| 338 | } |
| 339 | |
| 340 | template PDU_GTPU ts_GTP1U_GPDU(OCT4 teid, octetstring data) := |
| 341 | ts_GTP1U_PDU('FF'O, teid, { g_PDU_IEs := { data := data }}); |
| 342 | |
Harald Welte | 94ade36 | 2017-08-04 00:36:55 +0200 | [diff] [blame] | 343 | /* Altstep implementing responses to any incoming echo requests */ |
| 344 | altstep pingpong() runs on GT_CT { |
| 345 | var Gtp1cUnitdata ud; |
Harald Welte | 3af8948 | 2017-08-04 16:20:23 +0200 | [diff] [blame^] | 346 | var Gtp1uUnitdata udu; |
Harald Welte | 94ade36 | 2017-08-04 00:36:55 +0200 | [diff] [blame] | 347 | [] GTPC.receive(tr_GTPC_PING(?)) -> value ud { |
| 348 | GTPC.send(ts_GTPC_PONG(ud.peer, '00'O)); |
| 349 | repeat; |
| 350 | }; |
Harald Welte | 3af8948 | 2017-08-04 16:20:23 +0200 | [diff] [blame^] | 351 | [] GTPU.receive(tr_GTPU_PING(?)) -> value udu { |
| 352 | GTPU.send(ts_GTPU_PONG(udu.peer, '00'O)); |
| 353 | }; |
Harald Welte | 94ade36 | 2017-08-04 00:36:55 +0200 | [diff] [blame] | 354 | [] T_default.timeout { setverdict(fail); }; |
| 355 | } |
| 356 | |
| 357 | template octetstring t_ApnInternet := '08696E7465726E6574'O; |
| 358 | |
| 359 | function f_pdp_ctx_act(hexstring imsi, BIT4 nsapi, EndUserAddress eua, octetstring apn, octetstring msisdn) runs on GT_CT { |
| 360 | var Gtp1cUnitdata ud; |
| 361 | var octetstring teid := '01020304'O; |
| 362 | var default d; |
| 363 | |
| 364 | log("sending CreatePDP"); |
Harald Welte | 876345e | 2017-08-04 16:19:59 +0200 | [diff] [blame] | 365 | GTPC.send(ts_GTPC_CreatePDP(g_peer, imsi, g_restart_ctr, teid, teid, nsapi, eua, apn, g_sgsn_ip_c, g_sgsn_ip_u, msisdn)); |
Harald Welte | 94ade36 | 2017-08-04 00:36:55 +0200 | [diff] [blame] | 366 | T_default.start; |
| 367 | |
| 368 | d := activate(pingpong()); |
| 369 | alt { |
| 370 | [] GTPC.receive(tr_GTPC_MsgType(g_peer, createPDPContextResponse, teid)) -> value ud { |
| 371 | if (ud.gtpc.gtpc_pdu.createPDPContextResponse.cause.causevalue == '80'O) { |
| 372 | setverdict(pass); |
| 373 | } else { |
| 374 | setverdict(fail); |
| 375 | } |
| 376 | } |
| 377 | } |
| 378 | deactivate(d); |
| 379 | } |
| 380 | |
| 381 | testcase TC_activate_pdp4() runs on GT_CT { |
| 382 | f_init(); |
| 383 | var hexstring imsi := '262420123456789'H; |
| 384 | var octetstring msisdn := '1234'O; |
| 385 | f_pdp_ctx_act(imsi, '0010'B, valueof(t_EuaIPv4Dyn), valueof(t_ApnInternet), msisdn); |
| 386 | } |
| 387 | |
| 388 | testcase TC_activate_pdp6() runs on GT_CT { |
| 389 | f_init(); |
| 390 | var hexstring imsi := '262420123456789'H; |
| 391 | var octetstring msisdn := '1234'O; |
| 392 | f_pdp_ctx_act(imsi, '0010'B, valueof(t_EuaIPv6Dyn), valueof(t_ApnInternet), msisdn); |
| 393 | } |
| 394 | |
| 395 | |
| 396 | control { |
| 397 | execute(TC_activate_pdp4()); |
| 398 | execute(TC_activate_pdp6()); |
| 399 | } |
Harald Welte | 379d45a | 2017-08-03 09:55:15 +0200 | [diff] [blame] | 400 | } |