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; |
| 14 | const charstring g_bind_ip := "127.23.42.1"; |
| 15 | |
| 16 | type component GT_CT { |
| 17 | port GTPC_PT GTPC; |
| 18 | port GTPU_PT GTPU; |
| 19 | |
| 20 | var OCT1 g_restart_ctr := '01'O; |
| 21 | /* FIXME: unify with g_bind_ip + parse from config file */ |
| 22 | var OCT4 g_sgsn_ip := '7f172a01'O; |
| 23 | /* FIXME: parse remName from config file */ |
| 24 | var GtpPeer g_peer := { connId := 0, remName := "127.0.0.6", remPort := GTP1C_PORT }; |
| 25 | timer T_default := 3.0; |
| 26 | } |
| 27 | |
| 28 | function f_init() runs on GT_CT { |
| 29 | var Result res; |
| 30 | map(self:GTPC, system:GTPC); |
| 31 | res := GTP_CodecPort_CtrlFunct.f_IPL4_listen(GTPC, g_bind_ip, GTP1C_PORT, {udp:={}}); |
| 32 | log("GTP1C ConnectionID: ", res.connId); |
| 33 | g_peer.connId := res.connId; |
| 34 | |
| 35 | map(self:GTPU, system:GTPU); |
| 36 | GTP_CodecPort_CtrlFunct.f_GTPU_listen(GTPU, g_bind_ip, GTP1U_PORT, {udp:={}}); |
| 37 | } |
| 38 | |
| 39 | /* generalized GTP-C receive template */ |
| 40 | template PDU_GTPC tr_GTP1C_PDU(template OCT1 msg_type, template OCT4 teid) := { |
| 41 | /* N-PDU Number flag (PN) shall be set to '0'. A GTP-C receiver shall not return an |
| 42 | * error if this flag is set to '1'. */ |
| 43 | pn_bit := '0'B, |
| 44 | /* Sequence number flag (S) shall be set to '1'. */ |
| 45 | s_bit := '1'B, |
| 46 | e_bit := ?, |
| 47 | spare := ?, |
| 48 | /* Protocol Type flag (PT) shall be set to '1'.*/ |
| 49 | pt := '1'B, |
| 50 | /* Version shall be set to decimal 1 ('001'). */ |
| 51 | version := '001'B, |
| 52 | messageType := msg_type, |
| 53 | lengthf := ?, |
| 54 | teid := teid, |
| 55 | opt_part := *, |
| 56 | gtpc_pdu := ? |
| 57 | } |
| 58 | |
| 59 | /* generalized GTP-C send template */ |
| 60 | template PDU_GTPC ts_GTP1C_PDU(OCT1 msg_type, OCT4 teid, GTPC_PDUs pdu) := { |
| 61 | /* N-PDU Number flag (PN) shall be set to '0'. A GTP-C receiver shall not return an |
| 62 | * error if this flag is set to '1'. */ |
| 63 | pn_bit := '0'B, |
| 64 | /* Sequence number flag (S) shall be set to '1'. */ |
| 65 | s_bit := '1'B, |
| 66 | e_bit := '0'B, |
| 67 | spare := '0'B, |
| 68 | /* Protocol Type flag (PT) shall be set to '1'.*/ |
| 69 | pt := '1'B, |
| 70 | /* Version shall be set to decimal 1 ('001'). */ |
| 71 | version := '001'B, |
| 72 | messageType := msg_type, |
| 73 | lengthf := 0, /* we assume encoder overwrites this */ |
| 74 | teid := teid, |
| 75 | opt_part := { |
| 76 | sequenceNumber := '9801'O, |
| 77 | npduNumber := '00'O, |
| 78 | nextExtHeader := '00'O, |
| 79 | gTPC_extensionHeader_List := omit |
| 80 | }, |
| 81 | gtpc_pdu := pdu |
| 82 | } |
| 83 | |
| 84 | /* recovery IE */ |
| 85 | template Recovery_gtpc ts_Recovery(OCT1 restart_counter) := { |
| 86 | type_gtpc := '00'O, /* we assume encoder fixes this */ |
| 87 | restartCounter := restart_counter |
| 88 | } |
| 89 | |
| 90 | /* template matching reception of GTP-C echo-request */ |
| 91 | template Gtp1cUnitdata tr_GTPC_MsgType(template GtpPeer peer, template OCT1 msg_type, template OCT4 teid) := { |
| 92 | peer := peer, |
| 93 | gtpc := tr_GTP1C_PDU(msg_type, teid) |
| 94 | } |
| 95 | |
| 96 | /* template matching reception of GTP-C echo-request */ |
| 97 | template Gtp1cUnitdata tr_GTPC_PING(template GtpPeer peer) := tr_GTPC_MsgType(peer, echoRequest, '00000000'O); |
| 98 | |
| 99 | template GTPC_PDUs ts_EchoRespPDU(OCT1 restart_counter) := { |
| 100 | echoResponse := { |
| 101 | recovery := { |
| 102 | type_gtpc := '00'O, /* we assume encoder fixes? */ |
| 103 | restartCounter := restart_counter |
| 104 | }, |
| 105 | private_extension_gtpc := omit |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | /* master template for senidng a GTP-C echo response */ |
| 110 | template Gtp1cUnitdata ts_GTPC_PONG(GtpPeer peer, OCT1 rest_ctr) := { |
| 111 | peer := peer, |
| 112 | gtpc := ts_GTP1C_PDU(echoResponse, '00000000'O, valueof(ts_EchoRespPDU(rest_ctr))) |
| 113 | } |
| 114 | |
| 115 | template EndUserAddress t_EuaIPv4(template OCT4 ip_addr) := { |
| 116 | type_gtpc := '80'O, |
| 117 | endUserAddress := { |
| 118 | endUserAddressIPv4 := { |
| 119 | lengthf := 2, |
| 120 | pdp_typeorg := '0001'B, |
| 121 | spare := '1111'B, |
| 122 | pdp_typenum := '21'O, |
| 123 | ipv4_address := ip_addr |
| 124 | } |
| 125 | } |
| 126 | } |
| 127 | template EndUserAddress t_EuaIPv4Dyn := t_EuaIPv4(omit); |
| 128 | template EndUserAddress t_EuaIPv6(template OCT16 ip_addr) := { |
| 129 | type_gtpc := '80'O, |
| 130 | endUserAddress := { |
| 131 | endUserAddressIPv6 := { |
| 132 | lengthf := 2, |
| 133 | pdp_typeorg := '0001'B, |
| 134 | spare := '1111'B, |
| 135 | pdp_typenum := '57'O, |
| 136 | ipv6_address := ip_addr |
| 137 | } |
| 138 | } |
| 139 | } |
| 140 | template EndUserAddress t_EuaIPv6Dyn := t_EuaIPv6(omit); |
| 141 | |
| 142 | template AccessPointName ts_APN(octetstring apn) := { |
| 143 | type_gtpc := '83'O, |
| 144 | lengthf := lengthof(apn), |
| 145 | apn_value := apn |
| 146 | } |
| 147 | |
| 148 | template GSN_Address_GTPC ts_GsnAddr(octetstring ip_addr) := { |
| 149 | type_gtpc := '85'O, |
| 150 | lengthf := lengthof(ip_addr), |
| 151 | addressf := ip_addr |
| 152 | } |
| 153 | |
| 154 | template MSISDN ts_Msisdn(octetstring msisdn) := { |
| 155 | type_gtpc := '86'O, |
| 156 | lengthf := lengthof(msisdn), |
| 157 | msisdn := msisdn |
| 158 | } |
| 159 | |
| 160 | template QualityOfServiceProfile ts_QosDefault := { |
| 161 | type_gtpc := '87'O, |
| 162 | lengthf := 4, |
| 163 | allocRetensionPrio := '00'O, |
| 164 | qos_ProfileValue := { |
| 165 | reliabilityClass := '011'B, |
| 166 | delayClass := '001'B, |
| 167 | spare1 := '00'B, |
| 168 | precedenceClass := '010'B, |
| 169 | spare2 := '0'B, |
| 170 | peakThroughput := '1001'B, |
| 171 | meanThroughput := '11111'B, |
| 172 | spare3 := '000'B, |
| 173 | deliverErroneusSDU := omit, |
| 174 | deliveryOrder := omit, |
| 175 | trafficClass := omit, |
| 176 | maxSDUSize := omit, |
| 177 | maxBitrateUplink := omit, |
| 178 | maxBitrateDownlink := omit, |
| 179 | sduErrorRatio := omit, |
| 180 | residualBER := omit, |
| 181 | trafficHandlingPriority := omit, |
| 182 | transferDelay := omit, |
| 183 | guaranteedBitRateUplink := omit, |
| 184 | guaranteedBitRateDownlink := omit, |
| 185 | sourceStatisticsDescriptor := omit, |
| 186 | signallingIndication := omit, |
| 187 | spare4 := omit, |
| 188 | maxBitrateDownlinkExt := omit, |
| 189 | guaranteedBitRateDownlinkExt := omit, |
| 190 | maxBitrateUplinkExt := omit, |
| 191 | guaranteedBitRateUplinkExt := omit |
| 192 | } |
| 193 | } |
| 194 | |
| 195 | template IMSI_gtpc ts_Imsi(hexstring digits) := { |
| 196 | type_gtpc := '02'O, |
| 197 | digits := digits, |
| 198 | padding := 'F'H |
| 199 | } |
| 200 | |
| 201 | template GTPC_PDUs ts_CreatePdpPDU(hexstring imsi, OCT1 restart_ctr, OCT4 teid_data, OCT4 teid_ctrl, |
| 202 | BIT4 nsapi, EndUserAddress eua, octetstring apn, |
| 203 | octetstring sgsn_ip_sign, octetstring sgsn_ip_data, |
| 204 | octetstring msisdn) := { |
| 205 | createPDPContextRequest := { |
| 206 | imsi := ts_Imsi(imsi), |
| 207 | rai := omit, |
| 208 | recovery := ts_Recovery(restart_ctr), |
| 209 | selectionMode := { |
| 210 | type_gtpc := '0F'O, |
| 211 | selectModeValue := '00'B, |
| 212 | spare := '111111'B |
| 213 | }, |
| 214 | teidDataI := { |
| 215 | type_gtpc := '00'O, |
| 216 | teidDataI := teid_data |
| 217 | }, |
| 218 | teidControlPlane := { |
| 219 | type_gtpc := '00'O, |
| 220 | teidControlPlane := teid_ctrl |
| 221 | }, |
| 222 | nsapi := { |
| 223 | type_gtpc := '00'O, |
| 224 | nsapi := nsapi, |
| 225 | unused := '0000'B |
| 226 | }, |
| 227 | linked_nsapi := omit, |
| 228 | charging_char := omit, |
| 229 | trace_ref := omit, |
| 230 | trace_type := omit, |
| 231 | endUserAddress := eua, |
| 232 | accessPointName := ts_APN(apn), |
| 233 | protConfigOptions := omit, |
| 234 | sgsn_addr_signalling := ts_GsnAddr(sgsn_ip_sign), |
| 235 | sgsn_addr_traffic := ts_GsnAddr(sgsn_ip_data), |
| 236 | msisdn := ts_Msisdn(msisdn), |
| 237 | qualityOfServiceProfile := ts_QosDefault, |
| 238 | tft := omit, |
| 239 | triggerId := omit, |
| 240 | omcId := omit, |
| 241 | commonFlags := omit, |
| 242 | aPN_Restriction := omit, |
| 243 | ratType := omit, |
| 244 | userLocationInformation := omit, |
| 245 | mS_TimeZone := omit, |
| 246 | imeisv := omit, |
| 247 | camelChargingInformationContainer := omit, |
| 248 | additionalTraceInfo := omit, |
| 249 | correlationID := omit, |
| 250 | evolvedAllocationRetentionPriorityI := omit, |
| 251 | extendedCommonFlags := omit, |
| 252 | userCSGInformation := omit, |
| 253 | aPN_AMBR := omit, |
| 254 | signallingPriorityIndication := omit, |
| 255 | cN_OperatorSelectionEntity := omit, |
| 256 | private_extension_gtpc := omit |
| 257 | } |
| 258 | } |
| 259 | |
| 260 | template Gtp1cUnitdata ts_GTPC_CreatePDP(GtpPeer peer, hexstring imsi, OCT1 restart_ctr, OCT4 teid_data, |
| 261 | OCT4 teid_ctrl, BIT4 nsapi, EndUserAddress eua, |
| 262 | octetstring apn, octetstring sgsn_ip_sign, |
| 263 | octetstring sgsn_ip_data, octetstring msisdn) := { |
| 264 | peer := peer, |
| 265 | gtpc := ts_GTP1C_PDU(createPDPContextRequest, '00000000'O, |
| 266 | valueof(ts_CreatePdpPDU(imsi, restart_ctr, teid_data, teid_ctrl, |
| 267 | nsapi, eua, apn, sgsn_ip_sign, |
| 268 | sgsn_ip_data, msisdn))) |
| 269 | } |
| 270 | |
| 271 | /* Altstep implementing responses to any incoming echo requests */ |
| 272 | altstep pingpong() runs on GT_CT { |
| 273 | var Gtp1cUnitdata ud; |
| 274 | [] GTPC.receive(tr_GTPC_PING(?)) -> value ud { |
| 275 | GTPC.send(ts_GTPC_PONG(ud.peer, '00'O)); |
| 276 | repeat; |
| 277 | }; |
| 278 | //[] GTPU.receive(tr_GTP_PING(?)) {}; |
| 279 | [] T_default.timeout { setverdict(fail); }; |
| 280 | } |
| 281 | |
| 282 | template octetstring t_ApnInternet := '08696E7465726E6574'O; |
| 283 | |
| 284 | function f_pdp_ctx_act(hexstring imsi, BIT4 nsapi, EndUserAddress eua, octetstring apn, octetstring msisdn) runs on GT_CT { |
| 285 | var Gtp1cUnitdata ud; |
| 286 | var octetstring teid := '01020304'O; |
| 287 | var default d; |
| 288 | |
| 289 | log("sending CreatePDP"); |
| 290 | GTPC.send(ts_GTPC_CreatePDP(g_peer, imsi, g_restart_ctr, teid, teid, nsapi, eua, apn, g_sgsn_ip, g_sgsn_ip, msisdn)); |
| 291 | T_default.start; |
| 292 | |
| 293 | d := activate(pingpong()); |
| 294 | alt { |
| 295 | [] GTPC.receive(tr_GTPC_MsgType(g_peer, createPDPContextResponse, teid)) -> value ud { |
| 296 | if (ud.gtpc.gtpc_pdu.createPDPContextResponse.cause.causevalue == '80'O) { |
| 297 | setverdict(pass); |
| 298 | } else { |
| 299 | setverdict(fail); |
| 300 | } |
| 301 | } |
| 302 | } |
| 303 | deactivate(d); |
| 304 | } |
| 305 | |
| 306 | testcase TC_activate_pdp4() runs on GT_CT { |
| 307 | f_init(); |
| 308 | var hexstring imsi := '262420123456789'H; |
| 309 | var octetstring msisdn := '1234'O; |
| 310 | f_pdp_ctx_act(imsi, '0010'B, valueof(t_EuaIPv4Dyn), valueof(t_ApnInternet), msisdn); |
| 311 | } |
| 312 | |
| 313 | testcase TC_activate_pdp6() runs on GT_CT { |
| 314 | f_init(); |
| 315 | var hexstring imsi := '262420123456789'H; |
| 316 | var octetstring msisdn := '1234'O; |
| 317 | f_pdp_ctx_act(imsi, '0010'B, valueof(t_EuaIPv6Dyn), valueof(t_ApnInternet), msisdn); |
| 318 | } |
| 319 | |
| 320 | |
| 321 | control { |
| 322 | execute(TC_activate_pdp4()); |
| 323 | execute(TC_activate_pdp6()); |
| 324 | } |
Harald Welte | 379d45a | 2017-08-03 09:55:15 +0200 | [diff] [blame] | 325 | } |