blob: aa42759473481d7b479a35f01b4ed826f5c3e94d [file] [log] [blame]
Harald Welte34b5a952019-05-27 11:54:11 +02001/* GTP Templates in TTCN-3
2 * (C) 2018 Harald Welte <laforge@gnumonks.org>
3 * contributions by sysmocom - s.f.m.c. GmbH
4 * All rights reserved.
5 *
6 * Released under the terms of GNU General Public License, Version 2 or
7 * (at your option) any later version.
8 *
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 */
11
Harald Weltec69cf4e2018-02-17 20:57:02 +010012module GTP_Templates {
13
14 import from General_Types all;
15 import from Osmocom_Types all;
16 import from GTPC_Types all;
17 import from GTPU_Types all;
18 import from GTP_CodecPort all;
19 import from IPCP_Types all;
20
Harald Welte3b4c3562018-03-01 10:01:58 +010021 /* Table 38 of 3GPP TS 29.060 */
22 type enumerated GTP_Cause {
23 GTP_CAUSE_REQUEST_IMEI (1),
24 GTP_CAUSE_REQUEST_IMSI_AND_IMEI (2),
25 GTP_CAUSE_NO_IDENTITY_NEDED (3),
26 GTP_CAUSE_MS_REFUSES (4),
27 GTP_CAUSE_MS_IS_NOT_GPRS_RESPONDING (5),
28 /* reserved */
29 GTP_CAUSE_REQUEST_ACCEPTED (128)
30 /* FIXME */
31 };
32
Harald Weltec69cf4e2018-02-17 20:57:02 +010033 /* generalized GTP-C receive template */
34 template PDU_GTPC tr_GTP1C_PDU(template OCT1 msg_type, template OCT4 teid, template GTPC_PDUs pdu := ?) := {
35 /* N-PDU Number flag (PN) shall be set to '0'. A GTP-C receiver shall not return an
36 * error if this flag is set to '1'. */
37 pn_bit := '0'B,
38 /* Sequence number flag (S) shall be set to '1'. */
39 s_bit := '1'B,
40 e_bit := ?,
41 spare := ?,
42 /* Protocol Type flag (PT) shall be set to '1'.*/
43 pt := '1'B,
44 /* Version shall be set to decimal 1 ('001'). */
45 version := '001'B,
46 messageType := msg_type,
47 lengthf := ?,
48 teid := teid,
49 opt_part := *,
50 gtpc_pdu := pdu
51 }
52
53 /* generalized GTP-C send template */
54 template PDU_GTPC ts_GTP1C_PDU(OCT1 msg_type, OCT4 teid, GTPC_PDUs pdu, uint16_t seq_nr) := {
55 /* N-PDU Number flag (PN) shall be set to '0'. A GTP-C receiver shall not return an
56 * error if this flag is set to '1'. */
57 pn_bit := '0'B,
58 /* Sequence number flag (S) shall be set to '1'. */
59 s_bit := '1'B,
60 e_bit := '0'B,
61 spare := '0'B,
62 /* Protocol Type flag (PT) shall be set to '1'.*/
63 pt := '1'B,
64 /* Version shall be set to decimal 1 ('001'). */
65 version := '001'B,
66 messageType := msg_type,
67 lengthf := 0, /* we assume encoder overwrites this */
68 teid := teid,
69 opt_part := {
70 sequenceNumber := int2oct(seq_nr, 2),
71 npduNumber := '00'O,
72 nextExtHeader := '00'O,
73 gTPC_extensionHeader_List := omit
74 },
75 gtpc_pdu := pdu
76 }
77
78 /* recovery IE */
79 template Recovery_gtpc ts_Recovery(OCT1 restart_counter) := {
80 type_gtpc := '0E'O,
81 restartCounter := restart_counter
82 }
83
84 template Recovery_gtpc tr_Recovery(template OCT1 restart_counter) := {
85 type_gtpc := '0E'O,
86 restartCounter := restart_counter
87 }
88
89 /* template matching reception of GTP-C echo-request */
90 template Gtp1cUnitdata tr_GTPC_MsgType(template GtpPeer peer, template OCT1 msg_type, template OCT4 teid, template GTPC_PDUs pdus := ?) := {
91 peer := peer,
92 gtpc := tr_GTP1C_PDU(msg_type, teid, pdus)
93 }
94
95 /* template matching reception of GTP-C echo-request */
96 template Gtp1cUnitdata tr_GTPC_PING(template GtpPeer peer) := tr_GTPC_MsgType(peer, echoRequest, '00000000'O);
97
98 template GTPC_PDUs tr_EchoRespPDU(template OCT1 restart_counter) := {
99 echoResponse := {
100 recovery := tr_Recovery(restart_counter),
101 private_extension_gtpc := *
102 }
103 }
104
105 /* template matching reception of GTP-C echo-response */
106 template Gtp1cUnitdata tr_GTPC_PONG(template GtpPeer peer) := tr_GTPC_MsgType(peer, echoResponse, '00000000'O, tr_EchoRespPDU(?));
107
108 template GTPC_PDUs ts_EchoRespPDU(OCT1 restart_counter) := {
109 echoResponse := {
110 recovery := ts_Recovery(restart_counter),
111 private_extension_gtpc := omit
112 }
113 }
114
115 /* master template for senidng a GTP-C echo response */
116 template Gtp1cUnitdata ts_GTPC_PONG(GtpPeer peer, uint16_t seq, OCT1 rest_ctr) := {
117 peer := peer,
118 gtpc := ts_GTP1C_PDU(echoResponse, '00000000'O, valueof(ts_EchoRespPDU(rest_ctr)), seq)
119 }
120
121 template GTPC_PDUs ts_EchoReqPDU := {
122 echoRequest := {
123 private_extension_gtpc := omit
124 }
125 }
126
127 /* master template for sending a GTP-C echo request */
128 template Gtp1cUnitdata ts_GTPC_PING(GtpPeer peer, uint16_t seq) := {
129 peer := peer,
130 gtpc := ts_GTP1C_PDU(echoRequest, '00000000'O, valueof(ts_EchoReqPDU), seq)
131 }
132
133 template EndUserAddress t_EuaIPv4(template OCT4 ip_addr) := {
134 type_gtpc := '80'O,
135 endUserAddress := {
136 endUserAddressIPv4 := {
137 lengthf := 2,
138 pdp_typeorg := '0001'B,
139 spare := '1111'B,
140 pdp_typenum := '21'O,
141 ipv4_address := ip_addr
142 }
143 }
144 }
145 template EndUserAddress t_EuaIPv4Dyn := t_EuaIPv4(omit);
146 template EndUserAddress tr_EuaIPv4(template OCT4 ip_addr) modifies t_EuaIPv4 := {
147 endUserAddress := {
148 endUserAddressIPv4 := {
149 lengthf := 2+lengthof(ip_addr)
150 }
151 }
152 }
153
154 template EndUserAddress t_EuaIPv6(template OCT16 ip_addr) := {
155 type_gtpc := '80'O,
156 endUserAddress := {
157 endUserAddressIPv6 := {
158 lengthf := 2,
159 pdp_typeorg := '0001'B,
160 spare := '1111'B,
161 pdp_typenum := '57'O,
162 ipv6_address := ip_addr
163 }
164 }
165 }
166 template EndUserAddress t_EuaIPv6Dyn := t_EuaIPv6(omit);
167 template EndUserAddress tr_EuaIPv6(template OCT16 ip_addr) modifies t_EuaIPv6 := {
168 endUserAddress := {
169 endUserAddressIPv6 := {
170 lengthf := 2+lengthof(ip_addr)
171 }
172 }
173 }
174
Oliver Smithee6a0882019-03-08 11:05:46 +0100175 /* 3GPP TS 29.060 Figure 37A: End User Address Information Element for IPv4v6 (both static) */
176 template EndUserAddress t_EuaIPv4v6(template OCT4 ip_addr4, template OCT16 ip_addr6) := {
177 type_gtpc := '80'O,
178 endUserAddress := {
179 endUserAddressIPv4andIPv6 := {
180 lengthf := 2,
181 pdp_typeorg := '0001'B,
182 spare := '1111'B,
183 pdp_typenum := '8D'O,
184 ipv4_address := ip_addr4,
185 ipv6_address := ip_addr6
186 }
187 }
188 }
189 template EndUserAddress t_EuaIPv4Dynv6Dyn := t_EuaIPv4v6(omit, omit);
190 template EndUserAddress tr_EuaIPv4v6(template OCT4 ip_addr4, template OCT16 ip_addr6) modifies t_EuaIPv4v6 := {
191 endUserAddress := {
192 endUserAddressIPv4andIPv6 := {
193 lengthf := 2+lengthof(ip_addr4)+lengthof(ip_addr6)
194 }
195 }
196 }
197
Harald Weltec69cf4e2018-02-17 20:57:02 +0100198 template AccessPointName ts_APN(octetstring apn) := {
199 type_gtpc := '83'O,
200 lengthf := lengthof(apn),
201 apn_value := apn
202 }
203
204 template GSN_Address_GTPC ts_GsnAddr(octetstring ip_addr) := {
205 type_gtpc := '85'O,
206 lengthf := lengthof(ip_addr),
207 addressf := ip_addr
208 }
209
210 template MSISDN ts_Msisdn(octetstring msisdn) := {
211 type_gtpc := '86'O,
212 lengthf := lengthof(msisdn),
213 msisdn := msisdn
214 }
215
216 template QualityOfServiceProfile ts_QosDefault := {
217 type_gtpc := '87'O,
218 lengthf := 4,
219 allocRetensionPrio := '00'O,
220 qos_ProfileValue := {
221 reliabilityClass := '011'B,
222 delayClass := '001'B,
223 spare1 := '00'B,
224 precedenceClass := '010'B,
225 spare2 := '0'B,
226 peakThroughput := '1001'B,
227 meanThroughput := '11111'B,
228 spare3 := '000'B,
229 deliverErroneusSDU := omit,
230 deliveryOrder := omit,
231 trafficClass := omit,
232 maxSDUSize := omit,
233 maxBitrateUplink := omit,
234 maxBitrateDownlink := omit,
235 sduErrorRatio := omit,
236 residualBER := omit,
237 trafficHandlingPriority := omit,
238 transferDelay := omit,
239 guaranteedBitRateUplink := omit,
240 guaranteedBitRateDownlink := omit,
241 sourceStatisticsDescriptor := omit,
242 signallingIndication := omit,
243 spare4 := omit,
244 maxBitrateDownlinkExt := omit,
245 guaranteedBitRateDownlinkExt := omit,
246 maxBitrateUplinkExt := omit,
247 guaranteedBitRateUplinkExt := omit
248 }
249 }
250
251 template IMSI_gtpc ts_Imsi(hexstring digits) := {
252 type_gtpc := '02'O,
253 digits := digits,
254 padding := 'F'H
255 }
256
257 template GTPC_PDUs ts_CreatePdpPDU(hexstring imsi, OCT1 restart_ctr, OCT4 teid_data, OCT4 teid_ctrl,
258 BIT4 nsapi, EndUserAddress eua, octetstring apn,
259 octetstring sgsn_ip_sign, octetstring sgsn_ip_data,
260 octetstring msisdn, template ProtConfigOptions pco := omit) := {
261 createPDPContextRequest := {
262 imsi := ts_Imsi(imsi),
263 rai := omit,
264 recovery := ts_Recovery(restart_ctr),
265 selectionMode := {
266 type_gtpc := '0F'O,
267 selectModeValue := '00'B,
268 spare := '111111'B
269 },
270 teidDataI := {
271 type_gtpc := '00'O,
272 teidDataI := teid_data
273 },
274 teidControlPlane := {
275 type_gtpc := '00'O,
276 teidControlPlane := teid_ctrl
277 },
278 nsapi := {
279 type_gtpc := '00'O,
280 nsapi := nsapi,
281 unused := '0000'B
282 },
283 linked_nsapi := omit,
284 charging_char := omit,
285 trace_ref := omit,
286 trace_type := omit,
287 endUserAddress := eua,
288 accessPointName := ts_APN(apn),
289 protConfigOptions := pco,
290 sgsn_addr_signalling := ts_GsnAddr(sgsn_ip_sign),
291 sgsn_addr_traffic := ts_GsnAddr(sgsn_ip_data),
292 msisdn := ts_Msisdn(msisdn),
293 qualityOfServiceProfile := ts_QosDefault,
294 tft := omit,
295 triggerId := omit,
296 omcId := omit,
297 commonFlags := omit,
298 aPN_Restriction := omit,
299 ratType := omit,
300 userLocationInformation := omit,
301 mS_TimeZone := omit,
302 imeisv := omit,
303 camelChargingInformationContainer := omit,
304 additionalTraceInfo := omit,
305 correlationID := omit,
306 evolvedAllocationRetentionPriorityI := omit,
307 extendedCommonFlags := omit,
308 userCSGInformation := omit,
309 aPN_AMBR := omit,
310 signallingPriorityIndication := omit,
311 cN_OperatorSelectionEntity := omit,
312 private_extension_gtpc := omit
313 }
314 }
315
316 template Gtp1cUnitdata ts_GTPC_CreatePDP(GtpPeer peer, uint16_t seq, hexstring imsi,
317 OCT1 restart_ctr, OCT4 teid_data,
318 OCT4 teid_ctrl, BIT4 nsapi, EndUserAddress eua,
319 octetstring apn, octetstring sgsn_ip_sign,
320 octetstring sgsn_ip_data, octetstring msisdn,
321 template ProtConfigOptions pco := omit) := {
322 peer := peer,
323 gtpc := ts_GTP1C_PDU(createPDPContextRequest, '00000000'O,
324 valueof(ts_CreatePdpPDU(imsi, restart_ctr, teid_data, teid_ctrl,
325 nsapi, eua, apn, sgsn_ip_sign,
326 sgsn_ip_data, msisdn, pco)), seq)
327 }
328
Harald Welteeded9ad2018-02-17 20:57:34 +0100329
330 template NSAPI_GTPC ts_NSAPI(BIT4 nsapi) := {
331 type_gtpc := '14'O,
332 nsapi := nsapi,
333 unused := '0000'B
334 }
335
336 template ReorderingRequired ts_ReorderReq(boolean req := false) := {
337 type_gtpc := '08'O,
338 reordreq := bool2bit(req),
339 spare := '0000000'B
340 }
341
342 template GTPC_PDUs ts_CreatePdpRespPDU(OCT1 cause, OCT4 teid_data, OCT4 teid_ctrl, BIT4 nsapi,
343 octetstring ggsn_ip_sign, octetstring ggsn_ip_data,
Harald Welte7aff2ca2018-02-18 15:34:50 +0100344 OCT4 chg_id, template EndUserAddress eua := omit,
Pau Espin Pedrol94013452018-07-17 15:50:21 +0200345 template Recovery_gtpc recovery := omit,
Harald Welteeded9ad2018-02-17 20:57:34 +0100346 template ProtConfigOptions pco := omit) := {
347 createPDPContextResponse := {
348 cause := { '00'O, cause },
349 reorderingRequired := ts_ReorderReq(false),
Pau Espin Pedrol94013452018-07-17 15:50:21 +0200350 recovery := recovery,
Harald Welteeded9ad2018-02-17 20:57:34 +0100351 teidDataI := {
352 type_gtpc := '00'O,
353 teidDataI := teid_data
354 },
355 teidControlPlane := {
356 type_gtpc := '00'O,
357 teidControlPlane := teid_ctrl
358 },
359 nsapi := ts_NSAPI(nsapi),
Harald Welte7aff2ca2018-02-18 15:34:50 +0100360 chargingID := {
361 type_gtpc := '7F'O,
362 chargingID := chg_id
363 },
Harald Welteeded9ad2018-02-17 20:57:34 +0100364 endUserAddress := eua,
365 protConfigOptions := pco,
366 ggsn_addr_controlPlane := ts_GsnAddr(ggsn_ip_sign),
367 ggsn_addr_traffic := ts_GsnAddr(ggsn_ip_data),
368 alt_ggsn_addr_controlPane := omit,
369 alt_ggsn_addr_traffic := omit,
370 qualityOfServiceProfile := ts_QosDefault,
371 commonFlags := omit,
372 aPN_Restriction := omit,
373 mS_InfoChangeReportingAction := omit,
374 bearerControlMode := omit,
375 evolvedAllocationRetentionPriorityI := omit,
376 extendedCommonFlag := omit,
377 csg_information_reporting_action := omit,
378 aPN_AMBR := omit,
379 gGSN_BackOffTime := omit,
380 private_extension_gtpc := omit
381 }
382 }
383
384 template Gtp1cUnitdata ts_GTPC_CreatePdpResp(GtpPeer peer, uint16_t seq, OCT4 teid,
385 OCT1 cause,
386 OCT4 teid_ctrl, OCT4 teid_data,
387 BIT4 nsapi, octetstring ggsn_ip_sign,
Harald Welte7aff2ca2018-02-18 15:34:50 +0100388 octetstring ggsn_ip_data, OCT4 chg_id,
Harald Welteeded9ad2018-02-17 20:57:34 +0100389 template EndUserAddress eua := omit,
Pau Espin Pedrol94013452018-07-17 15:50:21 +0200390 template Recovery_gtpc recovery := omit,
Harald Welteeded9ad2018-02-17 20:57:34 +0100391 template ProtConfigOptions pco := omit) := {
392 peer := peer,
393 gtpc := ts_GTP1C_PDU(createPDPContextResponse, teid,
394 valueof(ts_CreatePdpRespPDU(cause, teid_data, teid_ctrl, nsapi,
Harald Welte7aff2ca2018-02-18 15:34:50 +0100395 ggsn_ip_sign, ggsn_ip_data, chg_id,
Pau Espin Pedrol94013452018-07-17 15:50:21 +0200396 eua, recovery, pco)), seq)
Harald Welteeded9ad2018-02-17 20:57:34 +0100397 }
398
Harald Weltec69cf4e2018-02-17 20:57:02 +0100399 /* PCO send base template */
400 template ProtConfigOptions ts_PCO := {
401 type_gtpc := '84'O,
402 lengthf := 0,
403 configProtocol := '000'B,
404 spare := '0000'B,
405 extension0 := '1'B,
406 protocols := {}
407 }
408 /* PCO receive base template */
409 template ProtConfigOptions tr_PCO := {
410 type_gtpc := '84'O,
411 lengthf := ?,
412 configProtocol := '000'B,
413 spare := ?,
414 extension0 := '1'B,
415 protocols := {}
416 }
417
418 template ProtConfigOptions ts_PCO_IPv6_DNS modifies ts_PCO := {
419 protocols := {
420 { protocolID := '0003'O, lengthProtoID := 0, protoIDContents := ''O }
421 }
422 }
423 template ProtConfigOptions tr_PCO_IPv6_DNS_resp(template OCT16 contents) modifies tr_PCO := {
424 protocols := {
425 *, { protocolID := '0003'O, lengthProtoID := 16, protoIDContents := contents }, *
426 }
427 }
428
429 template ProtConfigOptions ts_PCO_IPv4_DNS_IPCP modifies ts_PCO := {
430 protocols := {
431 /* dummy PAP entry to check if our parser in the GGSN can properly iterate over
432 * the list of protocols, see Change-Id Icc2e6716c33d78d3c3e000f529806228d8aa155e */
433 { protocolID := 'C023'O, lengthProtoID := 0, protoIDContents := ''O },
434 { protocolID := '8021'O, lengthProtoID := 16, protoIDContents :=
435 enc_IpcpPacket(valueof(ts_IPCP_ReqDNS)) }
436 }
437 }
438
Philipp Maier33e52612018-05-30 17:22:02 +0200439 template ProtConfigOptions ts_PCO_IPv4_PRI_DNS_IPCP modifies ts_PCO := {
440 protocols := {
441 /* dummy PAP entry to check if our parser can cope with a single primary DNS entry
442 * see Change-Id Icffde89f9bc5d8fcadf6e2dd6c0b4de03440edd5 and OS#3288 */
443 { protocolID := 'C023'O, lengthProtoID := 0, protoIDContents := ''O },
444 { protocolID := '8021'O, lengthProtoID := 16, protoIDContents :=
445 enc_IpcpPacket(valueof(ts_IPCP_ReqDNS_Primary)) }
446 }
447 }
448 template ProtConfigOptions ts_PCO_IPv4_SEC_DNS_IPCP modifies ts_PCO := {
449 protocols := {
450 /* dummy PAP entry to check if our parser can cope with a single secondary DNS entry
451 * see Change-Id Icffde89f9bc5d8fcadf6e2dd6c0b4de03440edd5 and OS#3288 */
452 { protocolID := 'C023'O, lengthProtoID := 0, protoIDContents := ''O },
453 { protocolID := '8021'O, lengthProtoID := 16, protoIDContents :=
454 enc_IpcpPacket(valueof(ts_IPCP_ReqDNS_Secondary)) }
455 }
456 }
457 template ProtConfigOptions ts_PCO_IPv4_SEPARATE_DNS_IPCP modifies ts_PCO := {
458 protocols := {
459 /* dummy PAP entry to check if our parser can cope with a primary and secondary DNS
460 * in separate IPCP containers OS#3381 */
461 { protocolID := 'C023'O, lengthProtoID := 0, protoIDContents := ''O },
462 { protocolID := '8021'O, lengthProtoID := 16, protoIDContents :=
463 enc_IpcpPacket(valueof(ts_IPCP_ReqDNS_Primary)) },
464 { protocolID := '8021'O, lengthProtoID := 16, protoIDContents :=
465 enc_IpcpPacket(valueof(ts_IPCP_ReqDNS_Secondary)) }
466 }
467 }
468
Harald Weltec69cf4e2018-02-17 20:57:02 +0100469 template ProtocolElement tr_PCO_Proto(OCT2 prot_id) := {
470 protocolID := prot_id,
471 lengthProtoID := ?,
472 protoIDContents := ?
473 }
Harald Weltef8298542019-04-10 10:15:28 +0200474 template ProtocolElement ts_PCOelem_PAP_broken := {
475 protocolID := 'C023'O,
476 lengthProtoID := 60,
477 /* PPP Password Authentication Protocol containing incorrect Peer-Id-Length set to 4 (6-7 should be the valid one), see OS#3914. */
478 protoIDContents := '0100003c'O & '0444435338323700bc1c08087c1508083e00790000150808fd06000001000000000000000000000000000000000000000000000000000000'O
479 }
480 template ProtConfigOptions ts_PCO_PAP_IPv4_DNS modifies ts_PCO := {
481 protocols := {
482 ts_PCOelem_PAP_broken,
483 { protocolID := '8021'O, lengthProtoID := 16, protoIDContents := enc_IpcpPacket(valueof(ts_IPCP_ReqDNS)) }
484 }
485 }
Harald Weltec69cf4e2018-02-17 20:57:02 +0100486 template ProtConfigOptions tr_PCO_Contains(OCT2 prot_id) modifies tr_PCO := {
487 protocols := { *, tr_PCO_Proto(prot_id), * }
488 }
489
490 template ProtConfigOptions ts_PCO_IPv4_DNS_CONT modifies ts_PCO := {
491 protocols := {
492 { protocolID := '000d'O, lengthProtoID := 0, protoIDContents := ''O }
493 }
494 }
495 template ProtConfigOptions tr_PCO_IPv4_DNS_CONT_resp(template OCT4 contents) modifies tr_PCO := {
496 protocols := {
497 *, { protocolID := '000d'O, lengthProtoID := 4, protoIDContents := contents }, *
498 }
499 }
500
501 /* extract a given protocol payload from PCO */
502 function f_PCO_extract_proto(ProtConfigOptions pco, OCT2 protocol, integer nth_match := 1) return octetstring {
503 var integer i;
504 var integer num_matches := 0;
505 for (i := 0; i < lengthof(pco.protocols); i := i + 1) {
506 if (pco.protocols[i].protocolID == protocol) {
507 num_matches := num_matches + 1;
508 if (num_matches == nth_match) {
509 return pco.protocols[i].protoIDContents;
510 }
511 }
512 }
Daniel Willmanne4ff5372018-07-05 17:35:03 +0200513 setverdict(fail, "Could not extract protocol payload from protocol ", protocol);
514 mtc.stop;
Harald Weltec69cf4e2018-02-17 20:57:02 +0100515 return ''O;
516 }
517
518 template IpcpPacket tr_IPCP(template LcpCode code, template uint8_t identifier,
519 template IpcpOptionList opts) := {
520 code := code,
521 identifier := identifier,
522 len := ?,
523 options := opts
524 }
525 template IpcpOption tr_IPCP_PrimaryDns(template OCT4 addr) := {
526 code := IPCP_OPT_PrimaryDNS,
527 len := 6,
528 data := addr
529 }
530 template IpcpOption tr_IPCP_SecondaryDns(template OCT4 addr) := {
531 code := IPCP_OPT_SecondaryDNS,
532 len := 6,
533 data := addr
534 }
535 template IpcpPacket tr_IPCP_Ack_DNS(template uint8_t identifier := ?, template OCT4 dns1 := ?,
536 template OCT4 dns2 := ?) :=
537 tr_IPCP(LCP_Configure_Ack, identifier,
538 { *, tr_IPCP_PrimaryDns(dns1), *, tr_IPCP_SecondaryDns(dns2), * });
539
540 template IpcpPacket ts_IPCP(LcpCode code, uint8_t identifier, template IpcpOptionList opts) := {
541 code := code,
542 identifier := identifier,
543 len := 0, /* overwritten */
544 options := opts
545 }
546 template IpcpPacket ts_IPCP_ReqDNS(uint8_t identifier := 0) :=
547 ts_IPCP(LCP_Configure_Request, identifier,
548 { tr_IPCP_PrimaryDns('00000000'O), tr_IPCP_SecondaryDns('00000000'O) });
549
Philipp Maier33e52612018-05-30 17:22:02 +0200550 template IpcpPacket ts_IPCP_ReqDNS_Primary(uint8_t identifier := 0) :=
551 ts_IPCP(LCP_Configure_Request, identifier,
552 { tr_IPCP_PrimaryDns('00000000'O) });
553 template IpcpPacket ts_IPCP_ReqDNS_Secondary(uint8_t identifier := 0) :=
554 ts_IPCP(LCP_Configure_Request, identifier,
555 { tr_IPCP_SecondaryDns('00000000'O) });
556
Harald Welte57b9b7f2018-02-18 22:28:13 +0100557 function f_teardown_ind_IE(in template (omit) BIT1 ind) return template (omit) TearDownInd {
558 if (istemplatekind(ind, "omit")) {
Harald Weltec69cf4e2018-02-17 20:57:02 +0100559 return omit;
560 }
Harald Weltec69cf4e2018-02-17 20:57:02 +0100561 var TearDownInd ret := {
562 type_gtpc := '13'O,
563 tdInd := valueof(ind),
564 spare:= '0000000'B
565 }
566 return ret;
567 }
568
Harald Welte57b9b7f2018-02-18 22:28:13 +0100569 template GTPC_PDUs ts_DeletePdpPDU(BIT4 nsapi, template (omit) BIT1 teardown_ind) := {
Harald Weltec69cf4e2018-02-17 20:57:02 +0100570 deletePDPContextRequest := {
571 cause := omit,
572 tearDownIndicator := f_teardown_ind_IE(teardown_ind),
573 nsapi := {
574 type_gtpc := '14'O,
575 nsapi := nsapi,
576 unused := '0000'B
577 },
578 protConfigOptions := omit,
579 userLocationInformation := omit,
580 mS_TimeZone := omit,
581 extendedCommonFlags := omit,
582 uLI_Timestamp := omit,
583 private_extension_gtpc := omit
584 }
585 }
586
587 template Gtp1cUnitdata ts_GTPC_DeletePDP(GtpPeer peer, uint16_t seq, OCT4 teid,
Harald Welte57b9b7f2018-02-18 22:28:13 +0100588 BIT4 nsapi, template (omit) BIT1 teardown_ind) := {
Harald Weltec69cf4e2018-02-17 20:57:02 +0100589 peer := peer,
590 gtpc := ts_GTP1C_PDU(deletePDPContextRequest, teid,
591 valueof(ts_DeletePdpPDU(nsapi, teardown_ind)), seq)
592 }
593
Harald Welte6f203162018-02-18 22:04:55 +0100594 template GTPC_PDUs ts_DeletePdpRespPDU(OCT1 cause,
595 template ProtConfigOptions pco := omit) := {
596 deletePDPContextResponse := {
597 cause := { '00'O, cause },
598 protConfigOptions := pco,
599 userLocationInformation := omit,
600 mS_TimeZone := omit,
601 uLI_Timestamp := omit,
602 private_extension_gtpc := omit
603 }
604 }
605
606 template Gtp1cUnitdata ts_GTPC_DeletePdpResp(GtpPeer peer, uint16_t seq, OCT4 teid,
607 OCT1 cause,
608 template ProtConfigOptions pco := omit) := {
609 peer := peer,
610 gtpc := ts_GTP1C_PDU(deletePDPContextResponse, teid,
611 valueof(ts_DeletePdpRespPDU(cause, pco)), seq)
612 }
613
614
Harald Weltec69cf4e2018-02-17 20:57:02 +0100615
616 /* GTP-U */
617
618 template PDU_GTPU tr_GTP1U_PDU(template OCT1 msg_type, template OCT4 teid, template GTPU_IEs ies := ?) := {
619 pn_bit := ?,
620 s_bit := ?,
621 e_bit := ?,
622 spare := ?,
623 /* Protocol Type flag (PT) shall be set to '1' in GTP */
624 pt := '1'B,
625 /* Version shall be set to decimal 1 ('001'). */
626 version := '001'B,
627 messageType := msg_type,
628 lengthf := ?,
629 teid := teid,
630 opt_part := *,
631 gtpu_IEs := ies
632 }
633
Stefan Sperlingc479e4f2018-04-03 19:34:16 +0200634 function f_GTPU_s_bit(template (omit) uint16_t seq) return BIT1 {
635 if (istemplatekind(seq, "omit")) {
636 return '0'B;
637 }
638 return '1'B;
639 }
640
641 function f_GTPU_opt_part(template (omit) uint16_t seq) return template (omit) GTPU_Header_optional_part {
642 if (istemplatekind(seq, "omit")) {
643 return omit;
644 }
645 var GTPU_Header_optional_part ret := {
646 sequenceNumber := int2oct(valueof(seq), 2),
647 npduNumber := '00'O,
648 nextExtHeader := '00'O,
649 gTPU_extensionHeader_List := omit
650 };
651 return ret;
652 }
653
Harald Weltec69cf4e2018-02-17 20:57:02 +0100654 /* generalized GTP-U send template */
Stefan Sperlingc479e4f2018-04-03 19:34:16 +0200655 template PDU_GTPU ts_GTP1U_PDU(OCT1 msg_type, template (omit) uint16_t seq, OCT4 teid, GTPU_IEs ies) := {
Harald Weltec69cf4e2018-02-17 20:57:02 +0100656 /* N-PDU Number flag (PN): the GTP-U header contains a meaningful N-PDU Number field if the PN
657 * flag is set to 1. */
658 pn_bit := '0'B, /* we assume the encoder overwrites this if an optional part is given */
659 /* If the Sequence Number flag (S) is set to '1' the sequence number field is present and
660 * meaningful otherwise it is set to '0'. For GTP-U messages Echo Request, Echo Response,
Stefan Sperlingc479e4f2018-04-03 19:34:16 +0200661 * Error Indication and Supported Extension Headers Notification, the S flag shall be set to '1'.
662 *
663 * Note that the caller must ensure that these conditions hold.
664 * The caller can either pass a sequence number (we set s_bit to '1'B) when appropriate,
665 * or may omit the sequence number (we set s_bit to '0'B). */
666 s_bit := f_GTPU_s_bit(seq),
Harald Weltec69cf4e2018-02-17 20:57:02 +0100667 /* Extension header presence */
668 e_bit := '0'B,
669 spare := '0'B,
670 /* Protocol Type flag (PT) shall be set to '1' in GTP */
671 pt := '1'B,
672 /* Version shall be set to decimal 1 ('001'). */
673 version := '001'B,
674 messageType := msg_type,
675 lengthf := 0, /* we assume encoder overwrites this */
676 teid := teid,
Stefan Sperlingc479e4f2018-04-03 19:34:16 +0200677 opt_part := f_GTPU_opt_part(seq),
Harald Weltec69cf4e2018-02-17 20:57:02 +0100678 gtpu_IEs := ies
679 }
680
681 template Gtp1uUnitdata tr_GTPU_MsgType(template GtpPeer peer, template OCT1 msg_type, template OCT4 teid) := {
682 peer := peer,
683 gtpu := tr_GTP1U_PDU(msg_type, teid)
684 }
685
686
687 /* template matching reception of GTP-U echo-request */
688 template Gtp1uUnitdata tr_GTPU_PING(template GtpPeer peer) := tr_GTPU_MsgType(peer, echoRequest, '00000000'O);
689
690 /* template matching reception of GTP-U GPDU */
691 template GTPU_IEs t_GPDU(template octetstring data) := {
692 g_PDU_IEs := {
693 data := data
694 }
695 }
696 template Gtp1uUnitdata tr_GTPU_GPDU(template GtpPeer peer, template OCT4 teid, template octetstring data := ?) := {
697 peer := peer,
698 gtpu := tr_GTP1U_PDU('FF'O, teid, t_GPDU(data))
699 }
700
701 template GTPU_IEs ts_UEchoRespPDU(OCT1 restart_counter) := {
702 echoResponse_IEs := {
703 recovery_gtpu := {
704 type_gtpu := '00'O, /* we assume encoder fixes? */
705 restartCounter := restart_counter
706 },
707 private_extension_gtpu := omit
708 }
709 }
710
711 /* master template for sending a GTP-U echo response */
712 template Gtp1uUnitdata ts_GTPU_PONG(GtpPeer peer, uint16_t seq, OCT1 rest_ctr) := {
713 peer := peer,
714 gtpu := ts_GTP1U_PDU(echoResponse, seq, '00000000'O, valueof(ts_UEchoRespPDU(rest_ctr)))
715 }
716
Pau Espin Pedrolf3e25382018-07-18 13:46:40 +0200717 template GSNAddress_gtpu ts_UGsnAddr(octetstring ip_addr) := {
718 type_gtpu := '85'O,
719 lengthf := lengthof(ip_addr),
720 gSNAddressValue := ip_addr
721 }
722
723 template TeidDataI_gtpu ts_UteidDataI(OCT4 teid) := {
724 type_gtpu := '10'O,
725 teidDataI := teid
726 }
727
728 template GTPU_IEs ts_UErrorIndication(OCT4 teid, octetstring gsn_addr) := {
729 errorIndication_IEs := {
730 teidDataI_gtpu := ts_UteidDataI(teid),
731 gSNAddress_gtpu := ts_UGsnAddr(gsn_addr),
732 private_extension_gtpu := omit
733 }
734 }
735
736 /* master template for sending a GTP-U Error indication */
737 template Gtp1uUnitdata ts_GTPU_ErrorIndication(GtpPeer peer, uint16_t seq, OCT4 teid, octetstring gsn_addr) := {
738 peer := peer,
739 gtpu := ts_GTP1U_PDU('1A'O, seq, '00000000'O, valueof(ts_UErrorIndication(teid, gsn_addr)))
740 }
741
Harald Weltec69cf4e2018-02-17 20:57:02 +0100742 /* master template for sending a GTP-U user plane data */
Stefan Sperlingc479e4f2018-04-03 19:34:16 +0200743 template Gtp1uUnitdata ts_GTP1U_GPDU(GtpPeer peer, template (omit) uint16_t seq, OCT4 teid, octetstring data) := {
Harald Weltec69cf4e2018-02-17 20:57:02 +0100744 peer := peer,
745 gtpu := ts_GTP1U_PDU('FF'O, seq, teid, { g_PDU_IEs := { data := data }})
746 }
747}