blob: 02a31b6b2d4586d507473e42793a795724648f9d [file] [log] [blame]
Harald Weltec69cf4e2018-02-17 20:57:02 +01001module GTP_Templates {
2
3 import from General_Types all;
4 import from Osmocom_Types all;
5 import from GTPC_Types all;
6 import from GTPU_Types all;
7 import from GTP_CodecPort all;
8 import from IPCP_Types all;
9
10 /* generalized GTP-C receive template */
11 template PDU_GTPC tr_GTP1C_PDU(template OCT1 msg_type, template OCT4 teid, template GTPC_PDUs pdu := ?) := {
12 /* N-PDU Number flag (PN) shall be set to '0'. A GTP-C receiver shall not return an
13 * error if this flag is set to '1'. */
14 pn_bit := '0'B,
15 /* Sequence number flag (S) shall be set to '1'. */
16 s_bit := '1'B,
17 e_bit := ?,
18 spare := ?,
19 /* Protocol Type flag (PT) shall be set to '1'.*/
20 pt := '1'B,
21 /* Version shall be set to decimal 1 ('001'). */
22 version := '001'B,
23 messageType := msg_type,
24 lengthf := ?,
25 teid := teid,
26 opt_part := *,
27 gtpc_pdu := pdu
28 }
29
30 /* generalized GTP-C send template */
31 template PDU_GTPC ts_GTP1C_PDU(OCT1 msg_type, OCT4 teid, GTPC_PDUs pdu, uint16_t seq_nr) := {
32 /* N-PDU Number flag (PN) shall be set to '0'. A GTP-C receiver shall not return an
33 * error if this flag is set to '1'. */
34 pn_bit := '0'B,
35 /* Sequence number flag (S) shall be set to '1'. */
36 s_bit := '1'B,
37 e_bit := '0'B,
38 spare := '0'B,
39 /* Protocol Type flag (PT) shall be set to '1'.*/
40 pt := '1'B,
41 /* Version shall be set to decimal 1 ('001'). */
42 version := '001'B,
43 messageType := msg_type,
44 lengthf := 0, /* we assume encoder overwrites this */
45 teid := teid,
46 opt_part := {
47 sequenceNumber := int2oct(seq_nr, 2),
48 npduNumber := '00'O,
49 nextExtHeader := '00'O,
50 gTPC_extensionHeader_List := omit
51 },
52 gtpc_pdu := pdu
53 }
54
55 /* recovery IE */
56 template Recovery_gtpc ts_Recovery(OCT1 restart_counter) := {
57 type_gtpc := '0E'O,
58 restartCounter := restart_counter
59 }
60
61 template Recovery_gtpc tr_Recovery(template OCT1 restart_counter) := {
62 type_gtpc := '0E'O,
63 restartCounter := restart_counter
64 }
65
66 /* template matching reception of GTP-C echo-request */
67 template Gtp1cUnitdata tr_GTPC_MsgType(template GtpPeer peer, template OCT1 msg_type, template OCT4 teid, template GTPC_PDUs pdus := ?) := {
68 peer := peer,
69 gtpc := tr_GTP1C_PDU(msg_type, teid, pdus)
70 }
71
72 /* template matching reception of GTP-C echo-request */
73 template Gtp1cUnitdata tr_GTPC_PING(template GtpPeer peer) := tr_GTPC_MsgType(peer, echoRequest, '00000000'O);
74
75 template GTPC_PDUs tr_EchoRespPDU(template OCT1 restart_counter) := {
76 echoResponse := {
77 recovery := tr_Recovery(restart_counter),
78 private_extension_gtpc := *
79 }
80 }
81
82 /* template matching reception of GTP-C echo-response */
83 template Gtp1cUnitdata tr_GTPC_PONG(template GtpPeer peer) := tr_GTPC_MsgType(peer, echoResponse, '00000000'O, tr_EchoRespPDU(?));
84
85 template GTPC_PDUs ts_EchoRespPDU(OCT1 restart_counter) := {
86 echoResponse := {
87 recovery := ts_Recovery(restart_counter),
88 private_extension_gtpc := omit
89 }
90 }
91
92 /* master template for senidng a GTP-C echo response */
93 template Gtp1cUnitdata ts_GTPC_PONG(GtpPeer peer, uint16_t seq, OCT1 rest_ctr) := {
94 peer := peer,
95 gtpc := ts_GTP1C_PDU(echoResponse, '00000000'O, valueof(ts_EchoRespPDU(rest_ctr)), seq)
96 }
97
98 template GTPC_PDUs ts_EchoReqPDU := {
99 echoRequest := {
100 private_extension_gtpc := omit
101 }
102 }
103
104 /* master template for sending a GTP-C echo request */
105 template Gtp1cUnitdata ts_GTPC_PING(GtpPeer peer, uint16_t seq) := {
106 peer := peer,
107 gtpc := ts_GTP1C_PDU(echoRequest, '00000000'O, valueof(ts_EchoReqPDU), seq)
108 }
109
110 template EndUserAddress t_EuaIPv4(template OCT4 ip_addr) := {
111 type_gtpc := '80'O,
112 endUserAddress := {
113 endUserAddressIPv4 := {
114 lengthf := 2,
115 pdp_typeorg := '0001'B,
116 spare := '1111'B,
117 pdp_typenum := '21'O,
118 ipv4_address := ip_addr
119 }
120 }
121 }
122 template EndUserAddress t_EuaIPv4Dyn := t_EuaIPv4(omit);
123 template EndUserAddress tr_EuaIPv4(template OCT4 ip_addr) modifies t_EuaIPv4 := {
124 endUserAddress := {
125 endUserAddressIPv4 := {
126 lengthf := 2+lengthof(ip_addr)
127 }
128 }
129 }
130
131 template EndUserAddress t_EuaIPv6(template OCT16 ip_addr) := {
132 type_gtpc := '80'O,
133 endUserAddress := {
134 endUserAddressIPv6 := {
135 lengthf := 2,
136 pdp_typeorg := '0001'B,
137 spare := '1111'B,
138 pdp_typenum := '57'O,
139 ipv6_address := ip_addr
140 }
141 }
142 }
143 template EndUserAddress t_EuaIPv6Dyn := t_EuaIPv6(omit);
144 template EndUserAddress tr_EuaIPv6(template OCT16 ip_addr) modifies t_EuaIPv6 := {
145 endUserAddress := {
146 endUserAddressIPv6 := {
147 lengthf := 2+lengthof(ip_addr)
148 }
149 }
150 }
151
152 template AccessPointName ts_APN(octetstring apn) := {
153 type_gtpc := '83'O,
154 lengthf := lengthof(apn),
155 apn_value := apn
156 }
157
158 template GSN_Address_GTPC ts_GsnAddr(octetstring ip_addr) := {
159 type_gtpc := '85'O,
160 lengthf := lengthof(ip_addr),
161 addressf := ip_addr
162 }
163
164 template MSISDN ts_Msisdn(octetstring msisdn) := {
165 type_gtpc := '86'O,
166 lengthf := lengthof(msisdn),
167 msisdn := msisdn
168 }
169
170 template QualityOfServiceProfile ts_QosDefault := {
171 type_gtpc := '87'O,
172 lengthf := 4,
173 allocRetensionPrio := '00'O,
174 qos_ProfileValue := {
175 reliabilityClass := '011'B,
176 delayClass := '001'B,
177 spare1 := '00'B,
178 precedenceClass := '010'B,
179 spare2 := '0'B,
180 peakThroughput := '1001'B,
181 meanThroughput := '11111'B,
182 spare3 := '000'B,
183 deliverErroneusSDU := omit,
184 deliveryOrder := omit,
185 trafficClass := omit,
186 maxSDUSize := omit,
187 maxBitrateUplink := omit,
188 maxBitrateDownlink := omit,
189 sduErrorRatio := omit,
190 residualBER := omit,
191 trafficHandlingPriority := omit,
192 transferDelay := omit,
193 guaranteedBitRateUplink := omit,
194 guaranteedBitRateDownlink := omit,
195 sourceStatisticsDescriptor := omit,
196 signallingIndication := omit,
197 spare4 := omit,
198 maxBitrateDownlinkExt := omit,
199 guaranteedBitRateDownlinkExt := omit,
200 maxBitrateUplinkExt := omit,
201 guaranteedBitRateUplinkExt := omit
202 }
203 }
204
205 template IMSI_gtpc ts_Imsi(hexstring digits) := {
206 type_gtpc := '02'O,
207 digits := digits,
208 padding := 'F'H
209 }
210
211 template GTPC_PDUs ts_CreatePdpPDU(hexstring imsi, OCT1 restart_ctr, OCT4 teid_data, OCT4 teid_ctrl,
212 BIT4 nsapi, EndUserAddress eua, octetstring apn,
213 octetstring sgsn_ip_sign, octetstring sgsn_ip_data,
214 octetstring msisdn, template ProtConfigOptions pco := omit) := {
215 createPDPContextRequest := {
216 imsi := ts_Imsi(imsi),
217 rai := omit,
218 recovery := ts_Recovery(restart_ctr),
219 selectionMode := {
220 type_gtpc := '0F'O,
221 selectModeValue := '00'B,
222 spare := '111111'B
223 },
224 teidDataI := {
225 type_gtpc := '00'O,
226 teidDataI := teid_data
227 },
228 teidControlPlane := {
229 type_gtpc := '00'O,
230 teidControlPlane := teid_ctrl
231 },
232 nsapi := {
233 type_gtpc := '00'O,
234 nsapi := nsapi,
235 unused := '0000'B
236 },
237 linked_nsapi := omit,
238 charging_char := omit,
239 trace_ref := omit,
240 trace_type := omit,
241 endUserAddress := eua,
242 accessPointName := ts_APN(apn),
243 protConfigOptions := pco,
244 sgsn_addr_signalling := ts_GsnAddr(sgsn_ip_sign),
245 sgsn_addr_traffic := ts_GsnAddr(sgsn_ip_data),
246 msisdn := ts_Msisdn(msisdn),
247 qualityOfServiceProfile := ts_QosDefault,
248 tft := omit,
249 triggerId := omit,
250 omcId := omit,
251 commonFlags := omit,
252 aPN_Restriction := omit,
253 ratType := omit,
254 userLocationInformation := omit,
255 mS_TimeZone := omit,
256 imeisv := omit,
257 camelChargingInformationContainer := omit,
258 additionalTraceInfo := omit,
259 correlationID := omit,
260 evolvedAllocationRetentionPriorityI := omit,
261 extendedCommonFlags := omit,
262 userCSGInformation := omit,
263 aPN_AMBR := omit,
264 signallingPriorityIndication := omit,
265 cN_OperatorSelectionEntity := omit,
266 private_extension_gtpc := omit
267 }
268 }
269
270 template Gtp1cUnitdata ts_GTPC_CreatePDP(GtpPeer peer, uint16_t seq, hexstring imsi,
271 OCT1 restart_ctr, OCT4 teid_data,
272 OCT4 teid_ctrl, BIT4 nsapi, EndUserAddress eua,
273 octetstring apn, octetstring sgsn_ip_sign,
274 octetstring sgsn_ip_data, octetstring msisdn,
275 template ProtConfigOptions pco := omit) := {
276 peer := peer,
277 gtpc := ts_GTP1C_PDU(createPDPContextRequest, '00000000'O,
278 valueof(ts_CreatePdpPDU(imsi, restart_ctr, teid_data, teid_ctrl,
279 nsapi, eua, apn, sgsn_ip_sign,
280 sgsn_ip_data, msisdn, pco)), seq)
281 }
282
283 /* PCO send base template */
284 template ProtConfigOptions ts_PCO := {
285 type_gtpc := '84'O,
286 lengthf := 0,
287 configProtocol := '000'B,
288 spare := '0000'B,
289 extension0 := '1'B,
290 protocols := {}
291 }
292 /* PCO receive base template */
293 template ProtConfigOptions tr_PCO := {
294 type_gtpc := '84'O,
295 lengthf := ?,
296 configProtocol := '000'B,
297 spare := ?,
298 extension0 := '1'B,
299 protocols := {}
300 }
301
302 template ProtConfigOptions ts_PCO_IPv6_DNS modifies ts_PCO := {
303 protocols := {
304 { protocolID := '0003'O, lengthProtoID := 0, protoIDContents := ''O }
305 }
306 }
307 template ProtConfigOptions tr_PCO_IPv6_DNS_resp(template OCT16 contents) modifies tr_PCO := {
308 protocols := {
309 *, { protocolID := '0003'O, lengthProtoID := 16, protoIDContents := contents }, *
310 }
311 }
312
313 template ProtConfigOptions ts_PCO_IPv4_DNS_IPCP modifies ts_PCO := {
314 protocols := {
315 /* dummy PAP entry to check if our parser in the GGSN can properly iterate over
316 * the list of protocols, see Change-Id Icc2e6716c33d78d3c3e000f529806228d8aa155e */
317 { protocolID := 'C023'O, lengthProtoID := 0, protoIDContents := ''O },
318 { protocolID := '8021'O, lengthProtoID := 16, protoIDContents :=
319 enc_IpcpPacket(valueof(ts_IPCP_ReqDNS)) }
320 }
321 }
322
323 template ProtocolElement tr_PCO_Proto(OCT2 prot_id) := {
324 protocolID := prot_id,
325 lengthProtoID := ?,
326 protoIDContents := ?
327 }
328 template ProtConfigOptions tr_PCO_Contains(OCT2 prot_id) modifies tr_PCO := {
329 protocols := { *, tr_PCO_Proto(prot_id), * }
330 }
331
332 template ProtConfigOptions ts_PCO_IPv4_DNS_CONT modifies ts_PCO := {
333 protocols := {
334 { protocolID := '000d'O, lengthProtoID := 0, protoIDContents := ''O }
335 }
336 }
337 template ProtConfigOptions tr_PCO_IPv4_DNS_CONT_resp(template OCT4 contents) modifies tr_PCO := {
338 protocols := {
339 *, { protocolID := '000d'O, lengthProtoID := 4, protoIDContents := contents }, *
340 }
341 }
342
343 /* extract a given protocol payload from PCO */
344 function f_PCO_extract_proto(ProtConfigOptions pco, OCT2 protocol, integer nth_match := 1) return octetstring {
345 var integer i;
346 var integer num_matches := 0;
347 for (i := 0; i < lengthof(pco.protocols); i := i + 1) {
348 if (pco.protocols[i].protocolID == protocol) {
349 num_matches := num_matches + 1;
350 if (num_matches == nth_match) {
351 return pco.protocols[i].protoIDContents;
352 }
353 }
354 }
355 setverdict(fail);
356 return ''O;
357 }
358
359 template IpcpPacket tr_IPCP(template LcpCode code, template uint8_t identifier,
360 template IpcpOptionList opts) := {
361 code := code,
362 identifier := identifier,
363 len := ?,
364 options := opts
365 }
366 template IpcpOption tr_IPCP_PrimaryDns(template OCT4 addr) := {
367 code := IPCP_OPT_PrimaryDNS,
368 len := 6,
369 data := addr
370 }
371 template IpcpOption tr_IPCP_SecondaryDns(template OCT4 addr) := {
372 code := IPCP_OPT_SecondaryDNS,
373 len := 6,
374 data := addr
375 }
376 template IpcpPacket tr_IPCP_Ack_DNS(template uint8_t identifier := ?, template OCT4 dns1 := ?,
377 template OCT4 dns2 := ?) :=
378 tr_IPCP(LCP_Configure_Ack, identifier,
379 { *, tr_IPCP_PrimaryDns(dns1), *, tr_IPCP_SecondaryDns(dns2), * });
380
381 template IpcpPacket ts_IPCP(LcpCode code, uint8_t identifier, template IpcpOptionList opts) := {
382 code := code,
383 identifier := identifier,
384 len := 0, /* overwritten */
385 options := opts
386 }
387 template IpcpPacket ts_IPCP_ReqDNS(uint8_t identifier := 0) :=
388 ts_IPCP(LCP_Configure_Request, identifier,
389 { tr_IPCP_PrimaryDns('00000000'O), tr_IPCP_SecondaryDns('00000000'O) });
390
391 function f_teardown_ind_IE(in template BIT1 ind) return template TearDownInd {
392/*
393 if (not isvalue(ind)) {
394 return omit;
395 }
396*/
397 var TearDownInd ret := {
398 type_gtpc := '13'O,
399 tdInd := valueof(ind),
400 spare:= '0000000'B
401 }
402 return ret;
403 }
404
405 template GTPC_PDUs ts_DeletePdpPDU(BIT4 nsapi, template BIT1 teardown_ind) := {
406 deletePDPContextRequest := {
407 cause := omit,
408 tearDownIndicator := f_teardown_ind_IE(teardown_ind),
409 nsapi := {
410 type_gtpc := '14'O,
411 nsapi := nsapi,
412 unused := '0000'B
413 },
414 protConfigOptions := omit,
415 userLocationInformation := omit,
416 mS_TimeZone := omit,
417 extendedCommonFlags := omit,
418 uLI_Timestamp := omit,
419 private_extension_gtpc := omit
420 }
421 }
422
423 template Gtp1cUnitdata ts_GTPC_DeletePDP(GtpPeer peer, uint16_t seq, OCT4 teid,
424 BIT4 nsapi, template BIT1 teardown_ind) := {
425 peer := peer,
426 gtpc := ts_GTP1C_PDU(deletePDPContextRequest, teid,
427 valueof(ts_DeletePdpPDU(nsapi, teardown_ind)), seq)
428 }
429
430
431 /* GTP-U */
432
433 template PDU_GTPU tr_GTP1U_PDU(template OCT1 msg_type, template OCT4 teid, template GTPU_IEs ies := ?) := {
434 pn_bit := ?,
435 s_bit := ?,
436 e_bit := ?,
437 spare := ?,
438 /* Protocol Type flag (PT) shall be set to '1' in GTP */
439 pt := '1'B,
440 /* Version shall be set to decimal 1 ('001'). */
441 version := '001'B,
442 messageType := msg_type,
443 lengthf := ?,
444 teid := teid,
445 opt_part := *,
446 gtpu_IEs := ies
447 }
448
449 /* generalized GTP-U send template */
450 template PDU_GTPU ts_GTP1U_PDU(OCT1 msg_type, uint16_t seq, OCT4 teid, GTPU_IEs ies) := {
451 /* N-PDU Number flag (PN): the GTP-U header contains a meaningful N-PDU Number field if the PN
452 * flag is set to 1. */
453 pn_bit := '0'B, /* we assume the encoder overwrites this if an optional part is given */
454 /* If the Sequence Number flag (S) is set to '1' the sequence number field is present and
455 * meaningful otherwise it is set to '0'. For GTP-U messages Echo Request, Echo Response,
456 * Error Indication and Supported Extension Headers Notification, the S flag shall be set to '1'. */
457 s_bit := '1'B, /* we assume the encoder overwrites this if an optional part is given */
458 /* Extension header presence */
459 e_bit := '0'B,
460 spare := '0'B,
461 /* Protocol Type flag (PT) shall be set to '1' in GTP */
462 pt := '1'B,
463 /* Version shall be set to decimal 1 ('001'). */
464 version := '001'B,
465 messageType := msg_type,
466 lengthf := 0, /* we assume encoder overwrites this */
467 teid := teid,
468 opt_part := {
469 sequenceNumber := int2oct(seq, 2),
470 npduNumber := '00'O,
471 nextExtHeader := '00'O,
472 gTPU_extensionHeader_List := omit
473 },
474 gtpu_IEs := ies
475 }
476
477 template Gtp1uUnitdata tr_GTPU_MsgType(template GtpPeer peer, template OCT1 msg_type, template OCT4 teid) := {
478 peer := peer,
479 gtpu := tr_GTP1U_PDU(msg_type, teid)
480 }
481
482
483 /* template matching reception of GTP-U echo-request */
484 template Gtp1uUnitdata tr_GTPU_PING(template GtpPeer peer) := tr_GTPU_MsgType(peer, echoRequest, '00000000'O);
485
486 /* template matching reception of GTP-U GPDU */
487 template GTPU_IEs t_GPDU(template octetstring data) := {
488 g_PDU_IEs := {
489 data := data
490 }
491 }
492 template Gtp1uUnitdata tr_GTPU_GPDU(template GtpPeer peer, template OCT4 teid, template octetstring data := ?) := {
493 peer := peer,
494 gtpu := tr_GTP1U_PDU('FF'O, teid, t_GPDU(data))
495 }
496
497 template GTPU_IEs ts_UEchoRespPDU(OCT1 restart_counter) := {
498 echoResponse_IEs := {
499 recovery_gtpu := {
500 type_gtpu := '00'O, /* we assume encoder fixes? */
501 restartCounter := restart_counter
502 },
503 private_extension_gtpu := omit
504 }
505 }
506
507 /* master template for sending a GTP-U echo response */
508 template Gtp1uUnitdata ts_GTPU_PONG(GtpPeer peer, uint16_t seq, OCT1 rest_ctr) := {
509 peer := peer,
510 gtpu := ts_GTP1U_PDU(echoResponse, seq, '00000000'O, valueof(ts_UEchoRespPDU(rest_ctr)))
511 }
512
513 /* master template for sending a GTP-U user plane data */
514 template Gtp1uUnitdata ts_GTP1U_GPDU(GtpPeer peer, uint16_t seq, OCT4 teid, octetstring data) := {
515 peer := peer,
516 gtpu := ts_GTP1U_PDU('FF'O, seq, teid, { g_PDU_IEs := { data := data }})
517 }
518}