lynxis lazus submitted this change.
gtpie: add gtp_encaps a modern encapsulation method
No idea why the previous ones started at the second IE.
Further add more length arguments to the encapsulation method.
Change-Id: I8bb086c568e07052c52d880df06049490346e91e
---
M gtp/gtpie.c
M include/osmocom/gtp/gtpie.h
2 files changed, 188 insertions(+), 0 deletions(-)
diff --git a/gtp/gtpie.c b/gtp/gtpie.c
index b3f2ff7..84a3ec2 100644
--- a/gtp/gtpie.c
+++ b/gtp/gtpie.c
@@ -944,3 +944,189 @@
}
return 0;
}
+
+/*! Encode GTP packet payload from Array of Information Elements.
+ * \param[in] ie Input Array of GTPIE
+ * \param[in] ie_len Length of \a ie array
+ * \param[in] pack Pointer to caller-allocated buffer for raw GTP packet (GTPIE_MAX length)
+ * \param[in] pack_len Length of \a pack buffer
+ * \param[out] encoded_len Encoded length of \a pack in bytes
+ * \returns 0 on success; 2 for out-of-space
+ * GTP requires a certain order, the call must follow those which are defined for every message */
+int gtpie_encaps3(union gtpie_member *ies[], unsigned int ie_len,
+ void *pack, unsigned pack_len, unsigned *encoded_len)
+{
+ unsigned int i;
+ unsigned char *p;
+ unsigned char *end;
+ int iesize;
+ union gtpie_member *ie;
+
+ *encoded_len = 0;
+ p = pack;
+
+ memset(pack, 0, pack_len);
+ end = p + pack_len;
+ for (i = 0; i < ie_len; i++) {
+ if (!ies[i])
+ continue;
+ ie = ies[i];
+
+ if (GTPIE_DEBUG)
+ printf
+ ("gtpie_encaps. Number %d, Type %d\n",
+ i, ie->t);
+ switch (ie->t) {
+ case GTPIE_CAUSE: /* TV GTPIE types with value length 1 */
+ case GTPIE_REORDER:
+ case GTPIE_MAP_CAUSE:
+ case GTPIE_MS_VALIDATED:
+ case GTPIE_RECOVERY:
+ case GTPIE_SELECTION_MODE:
+ case GTPIE_TEARDOWN:
+ case GTPIE_NSAPI:
+ case GTPIE_RANAP_CAUSE:
+ case GTPIE_RP_SMS:
+ case GTPIE_RP:
+ case GTPIE_MS_NOT_REACH:
+ case GTPIE_BCM:
+ iesize = 2;
+ break;
+ case GTPIE_PFI: /* TV GTPIE types with value length 2 */
+ case GTPIE_CHARGING_C:
+ case GTPIE_TRACE_REF:
+ case GTPIE_TRACE_TYPE:
+ iesize = 3;
+ break;
+ case GTPIE_QOS_PROFILE0: /* TV GTPIE types with value length 3 */
+ case GTPIE_P_TMSI_S:
+ iesize = 4;
+ break;
+ case GTPIE_TLLI: /* TV GTPIE types with value length 4 */
+ case GTPIE_P_TMSI:
+ case GTPIE_TEI_DI:
+ case GTPIE_TEI_C:
+ case GTPIE_CHARGING_ID:
+ iesize = 5;
+ break;
+ case GTPIE_TEI_DII: /* TV GTPIE types with value length 5 */
+ iesize = 6;
+ break;
+ case GTPIE_RAI: /* TV GTPIE types with value length 6 */
+ iesize = 7;
+ break;
+ case GTPIE_RAB_CONTEXT: /* TV GTPIE types with value length 7 */
+ iesize = 8;
+ break;
+ case GTPIE_IMSI: /* TV GTPIE types with value length 8 */
+ iesize = 9;
+ break;
+ case GTPIE_AUTH_TRIPLET: /* TV GTPIE types with value length 28 */
+ iesize = 29;
+ break;
+ case GTPIE_EXT_HEADER_T: /* GTP extension header */
+ iesize = 2 + hton8(ie->ext.l);
+ break;
+ case GTPIE_EUA: /* TLV GTPIE types with length length 2 */
+ case GTPIE_MM_CONTEXT:
+ case GTPIE_PDP_CONTEXT:
+ case GTPIE_APN:
+ case GTPIE_PCO:
+ case GTPIE_GSN_ADDR:
+ case GTPIE_MSISDN:
+ case GTPIE_QOS_PROFILE:
+ case GTPIE_AUTH_QUINTUP:
+ case GTPIE_TFT:
+ case GTPIE_TARGET_INF:
+ case GTPIE_UTRAN_TRANS:
+ case GTPIE_RAB_SETUP:
+ case GTPIE_TRIGGER_ID:
+ case GTPIE_OMC_ID:
+ case GTPIE_RAN_T_CONTAIN:
+ case GTPIE_PDP_CTX_PRIO:
+ case GTPIE_ADDL_RAB_S_I:
+ case GTPIE_SGSN_NUMBER:
+ case GTPIE_COMMON_FLAGS:
+ case GTPIE_APN_RESTR:
+ case GTPIE_R_PRIO_LCS:
+ case GTPIE_RAT_TYPE:
+ case GTPIE_USER_LOC:
+ case GTPIE_MS_TZ:
+ case GTPIE_IMEI_SV:
+ case GTPIE_CML_CHG_I_CT:
+ case GTPIE_MBMS_UE_CTX:
+ case GTPIE_TMGI:
+ case GTPIE_RIM_ROUT_ADDR:
+ case GTPIE_MBMS_PCO:
+ case GTPIE_MBMS_SA:
+ case GTPIE_SRNC_PDCP_CTX:
+ case GTPIE_ADDL_TRACE:
+ case GTPIE_HOP_CTR:
+ case GTPIE_SEL_PLMN_ID:
+ case GTPIE_MBMS_SESS_ID:
+ case GTPIE_MBMS_2_3G_IND:
+ case GTPIE_ENH_NSAPI:
+ case GTPIE_MBMS_SESS_DUR:
+ case GTPIE_A_MBMS_TRAC_I:
+ case GTPIE_MBMS_S_REP_N:
+ case GTPIE_MBMS_TTDT:
+ case GTPIE_PS_HO_REQ_CTX:
+ case GTPIE_BSS_CONTAINER:
+ case GTPIE_CELL_ID:
+ case GTPIE_PDU_NUMBERS:
+ case GTPIE_BSSGP_CAUSE:
+ case GTPIE_RQD_MBMS_BCAP:
+ case GTPIE_RIM_RA_DISCR:
+ case GTPIE_L_SETUP_PFCS:
+ case GTPIE_PS_HO_XID_PAR:
+ case GTPIE_MS_CHG_REP_A:
+ case GTPIE_DIR_TUN_FLAGS:
+ case GTPIE_CORREL_ID:
+ case GTPIE_MBMS_FLOWI:
+ case GTPIE_MBMS_MC_DIST:
+ case GTPIE_MBMS_DIST_ACK:
+ case GTPIE_R_IRAT_HO_INF:
+ case GTPIE_RFSP_IDX:
+ case GTPIE_FQDN:
+ case GTPIE_E_ALL_PRIO_1:
+ case GTPIE_E_ALL_PRIO_2:
+ case GTPIE_E_CMN_FLAGS:
+ case GTPIE_U_CSG_INFO:
+ case GTPIE_CSG_I_REP_ACT:
+ case GTPIE_CSG_ID:
+ case GTPIE_CSG_MEMB_IND:
+ case GTPIE_AMBR:
+ case GTPIE_UE_NET_CAPA:
+ case GTPIE_UE_AMBR:
+ case GTPIE_APN_AMBR_NS:
+ case GTPIE_GGSN_BACKOFF:
+ case GTPIE_S_PRIO_IND:
+ case GTPIE_S_PRIO_IND_NS:
+ case GTPIE_H_BR_16MBPS_F:
+ case GTPIE_A_MMCTX_SRVCC:
+ case GTPIE_A_FLAGS_SRVCC:
+ case GTPIE_STN_SR:
+ case GTPIE_C_MSISDN:
+ case GTPIE_E_RANAP_CAUSE:
+ case GTPIE_ENODEB_ID:
+ case GTPIE_SEL_MODE_NS:
+ case GTPIE_ULI_TIMESTAMP:
+ case GTPIE_CHARGING_ADDR:
+ case GTPIE_PRIVATE:
+ iesize = 3 + hton16(ie->tlv.l);
+ break;
+ default:
+ return 2; /* We received something unknown */
+ }
+
+ if (p + iesize < end) {
+ memcpy(p, ie, iesize);
+ p += iesize;
+ *encoded_len += iesize;
+ } else
+ return 2; /* Out of space */
+ }
+
+ return 0;
+}
+
diff --git a/include/osmocom/gtp/gtpie.h b/include/osmocom/gtp/gtpie.h
index b6fea6e..b3e3ddf 100644
--- a/include/osmocom/gtp/gtpie.h
+++ b/include/osmocom/gtp/gtpie.h
@@ -321,5 +321,7 @@
extern int gtpie_encaps(union gtpie_member *ie[], void *pack, unsigned *len);
extern int gtpie_encaps2(union gtpie_member ie[], unsigned int size,
void *pack, unsigned *len);
+extern int gtpie_encaps3(union gtpie_member *ie[], unsigned int ie_len,
+ void *pack, unsigned pack_len, unsigned *encoded_len);
#endif /* !_GTPIE_H */
To view, visit change 39032. To unsubscribe, or for help writing mail filters, visit settings.