예제 #1
0
/* 10.3.4 */
static int gsm_plmnsel_decode(struct osim_decoded_data *dd,
			      const struct osim_file_desc *desc,
			      int len, uint8_t *data)
{
	int i, n_plmn = len / 3;

	if (n_plmn < 1)
		return -EINVAL;

	for (i = 0; i < n_plmn; i++) {
		uint8_t *cur = data + 3*i;
		struct osim_decoded_element *elem, *mcc, *mnc;
		uint8_t ra_buf[6];
		struct gprs_ra_id ra_id;

		memset(ra_buf, 0, sizeof(ra_buf));
		memcpy(ra_buf, cur, 3);
		gsm48_parse_ra(&ra_id, ra_buf);

		elem = element_alloc(dd, "PLMN", ELEM_T_GROUP, ELEM_REPR_NONE);

		mcc = element_alloc_sub(elem, "MCC", ELEM_T_UINT16, ELEM_REPR_DEC);
		mcc->u.u16 = ra_id.mcc;

		mnc = element_alloc_sub(elem, "MNC", ELEM_T_UINT16, ELEM_REPR_DEC);
		mnc->u.u16 = ra_id.mnc;
	}

	return 0;
}
예제 #2
0
static inline void check_ra(const struct gprs_ra_id *raid)
{
	struct gsm48_ra_id ra;
	struct gprs_ra_id raid0 = {
		.mnc = 0,
		.mcc = 0,
		.lac = 0,
		.rac = 0,
	};

	gsm48_encode_ra(&ra, raid);
	printf("Constructed RA:\n");

	gsm48_parse_ra(&raid0, (const uint8_t *)&ra);
	dump_ra(raid);
	printf("MCC+MNC in BCD: %s\n", osmo_hexdump(ra.digits, sizeof(ra.digits)));
	dump_ra(&raid0);
	printf("RA test...");
	if (raid->mnc != raid0.mnc || raid->mcc != raid0.mcc || raid->lac != raid0.lac || raid->rac != raid0.rac
	    || (raid->mnc_3_digits || raid->mnc > 99) != raid0.mnc_3_digits)
		printf("FAIL\n");
	else
		printf("passed\n");
}

static inline void check_lai(const struct gprs_ra_id *raid)
{
	int rc;
	struct gsm48_loc_area_id lai = {};
	struct gprs_ra_id decoded = {};
	struct gprs_ra_id _laid = *raid;
	struct gprs_ra_id *laid = &_laid;
	laid->rac = 0;

	printf("- gsm48_generate_lai() from "); dump_ra(laid);

	gsm48_generate_lai(&lai, laid->mcc, laid->mnc, laid->lac);
	printf("  Encoded %s\n", osmo_hexdump((unsigned char*)&lai, sizeof(lai)));
	rc = gsm48_decode_lai(&lai, &decoded.mcc, &decoded.mnc, &decoded.lac);
	if (rc) {
		printf("  gsm48_decode_lai() returned %d --> FAIL\n", rc);
		return;
	}
	printf("  gsm48_decode_lai() gives  "); dump_ra(&decoded);
	if (decoded.mcc == laid->mcc
	    && decoded.mnc == laid->mnc
	    && decoded.lac == laid->lac)
		printf("  passed\n");
	else
		printf("  FAIL\n");
}
예제 #3
0
static void gbprox_vty_print_peer(struct vty *vty, struct gbproxy_peer *peer)
{
	struct gprs_ra_id raid;
	gsm48_parse_ra(&raid, peer->ra);

	vty_out(vty, "NSEI %5u, PTP-BVCI %5u, "
		"RAI %u-%u-%u-%u",
		peer->nsei, peer->bvci,
		raid.mcc, raid.mnc, raid.lac, raid.rac);
	if (peer->blocked)
		vty_out(vty, " [BVC-BLOCKED]");

	vty_out(vty, "%s", VTY_NEWLINE);
}
예제 #4
0
void gprs_gb_log_parse_context(struct gprs_gb_parse_context *parse_ctx,
			       const char *default_msg_name)
{
	const char *msg_name = default_msg_name;
	const char *sep = "";

	if (!parse_ctx->tlli_enc &&
	    !parse_ctx->ptmsi_enc &&
	    !parse_ctx->new_ptmsi_enc &&
	    !parse_ctx->imsi)
		return;

	if (parse_ctx->llc_msg_name)
		msg_name = parse_ctx->llc_msg_name;

	LOGP(DGPRS, LOGL_DEBUG, "%s: Got", msg_name);

	if (parse_ctx->tlli_enc) {
		LOGP(DGPRS, LOGL_DEBUG, "%s TLLI %08x", sep, parse_ctx->tlli);
		sep = ",";
	}

	if (parse_ctx->old_tlli_enc) {
		LOGP(DGPRS, LOGL_DEBUG, "%s old TLLI %02x%02x%02x%02x", sep,
		     parse_ctx->old_tlli_enc[0],
		     parse_ctx->old_tlli_enc[1],
		     parse_ctx->old_tlli_enc[2],
		     parse_ctx->old_tlli_enc[3]);
		sep = ",";
	}

	if (parse_ctx->bssgp_raid_enc) {
		struct gprs_ra_id raid;
		gsm48_parse_ra(&raid, parse_ctx->bssgp_raid_enc);
		LOGP(DGPRS, LOGL_DEBUG, "%s BSSGP RAID %u-%u-%u-%u", sep,
		     raid.mcc, raid.mnc, raid.lac, raid.rac);
		sep = ",";
	}

	if (parse_ctx->raid_enc) {
		struct gprs_ra_id raid;
		gsm48_parse_ra(&raid, parse_ctx->raid_enc);
		LOGP(DGPRS, LOGL_DEBUG, "%s RAID %u-%u-%u-%u", sep,
		     raid.mcc, raid.mnc, raid.lac, raid.rac);
		sep = ",";
	}

	if (parse_ctx->old_raid_enc) {
		struct gprs_ra_id raid;
		gsm48_parse_ra(&raid, parse_ctx->old_raid_enc);
		LOGP(DGPRS, LOGL_DEBUG, "%s old RAID %u-%u-%u-%u", sep,
		     raid.mcc, raid.mnc, raid.lac, raid.rac);
		sep = ",";
	}

	if (parse_ctx->ptmsi_enc) {
		uint32_t ptmsi = GSM_RESERVED_TMSI;
		int ok;
		ok = gprs_parse_mi_tmsi(parse_ctx->ptmsi_enc, GSM48_TMSI_LEN, &ptmsi);
		LOGP(DGPRS, LOGL_DEBUG, "%s PTMSI %08x%s",
		     sep, ptmsi, ok ? "" : " (parse error)");
		sep = ",";
	}

	if (parse_ctx->new_ptmsi_enc) {
		uint32_t new_ptmsi = GSM_RESERVED_TMSI;
		int ok;
		ok = gprs_parse_mi_tmsi(parse_ctx->new_ptmsi_enc, GSM48_TMSI_LEN,
					&new_ptmsi);
		LOGP(DGPRS, LOGL_DEBUG, "%s new PTMSI %08x%s",
		     sep, new_ptmsi, ok ? "" : " (parse error)");
		sep = ",";
	}

	if (parse_ctx->imsi) {
		char mi_buf[200];
		mi_buf[0] = '\0';
		gsm48_mi_to_string(mi_buf, sizeof(mi_buf),
				   parse_ctx->imsi, parse_ctx->imsi_len);
		LOGP(DGPRS, LOGL_DEBUG, "%s IMSI %s",
		     sep, mi_buf);
		sep = ",";
	}
	if (parse_ctx->invalidate_tlli) {
		LOGP(DGPRS, LOGL_DEBUG, "%s invalidate", sep);
		sep = ",";
	}

	LOGP(DGPRS, LOGL_DEBUG, "\n");
}
예제 #5
0
/* Parse a single GMM-PAGING.req to a given NSEI/NS-BVCI */
int bssgp_rx_paging(struct bssgp_paging_info *pinfo,
		    struct msgb *msg)
{
	struct bssgp_normal_hdr *bgph =
			(struct bssgp_normal_hdr *) msgb_bssgph(msg);
	struct tlv_parsed tp;
	uint8_t ra[6];
	int rc, data_len;

	memset(ra, 0, sizeof(ra));

	data_len = msgb_bssgp_len(msg) - sizeof(*bgph);
	rc = bssgp_tlv_parse(&tp, bgph->data, data_len);
	if (rc < 0)
		goto err_mand_ie;

	switch (bgph->pdu_type) {
	case BSSGP_PDUT_PAGING_PS:
		pinfo->mode = BSSGP_PAGING_PS;
		break;
	case BSSGP_PDUT_PAGING_CS:
		pinfo->mode = BSSGP_PAGING_CS;
		break;
	default:
		return -EINVAL;
	}

	/* IMSI */
	if (!TLVP_PRESENT(&tp, BSSGP_IE_IMSI))
		goto err_mand_ie;
	if (!pinfo->imsi)
		pinfo->imsi = talloc_zero_size(pinfo, GSM_IMSI_LENGTH);
	gsm48_mi_to_string(pinfo->imsi, GSM_IMSI_LENGTH,
			   TLVP_VAL(&tp, BSSGP_IE_IMSI),
			   TLVP_LEN(&tp, BSSGP_IE_IMSI));

	/* DRX Parameters */
	if (!TLVP_PRESENT(&tp, BSSGP_IE_DRX_PARAMS))
		goto err_mand_ie;
	pinfo->drx_params = ntohs(*(uint16_t *)TLVP_VAL(&tp, BSSGP_IE_DRX_PARAMS));

	/* Scope */
	if (TLVP_PRESENT(&tp, BSSGP_IE_BSS_AREA_ID)) {
		pinfo->scope = BSSGP_PAGING_BSS_AREA;
	} else if (TLVP_PRESENT(&tp, BSSGP_IE_LOCATION_AREA)) {
		pinfo->scope = BSSGP_PAGING_LOCATION_AREA;
		memcpy(ra, TLVP_VAL(&tp, BSSGP_IE_LOCATION_AREA),
			TLVP_LEN(&tp, BSSGP_IE_LOCATION_AREA));
		gsm48_parse_ra(&pinfo->raid, ra);
	} else if (TLVP_PRESENT(&tp, BSSGP_IE_ROUTEING_AREA)) {
		pinfo->scope = BSSGP_PAGING_ROUTEING_AREA;
		memcpy(ra, TLVP_VAL(&tp, BSSGP_IE_ROUTEING_AREA),
			TLVP_LEN(&tp, BSSGP_IE_ROUTEING_AREA));
		gsm48_parse_ra(&pinfo->raid, ra);
	} else if (TLVP_PRESENT(&tp, BSSGP_IE_BVCI)) {
		pinfo->scope = BSSGP_PAGING_BVCI;
		pinfo->bvci = ntohs(*(uint16_t *)TLVP_VAL(&tp, BSSGP_IE_BVCI));
	} else
		return -EINVAL;

	/* QoS profile mandatory for PS */
	if (pinfo->mode == BSSGP_PAGING_PS) {
		if (!TLVP_PRESENT(&tp, BSSGP_IE_QOS_PROFILE))
			goto err_cond_ie;
		if (TLVP_LEN(&tp, BSSGP_IE_QOS_PROFILE) < 3)
			goto err;

		memcpy(&pinfo->qos, TLVP_VAL(&tp, BSSGP_IE_QOS_PROFILE),
			3);
	}

	/* Optional (P-)TMSI */
	if (TLVP_PRESENT(&tp, BSSGP_IE_TMSI) &&
	    TLVP_LEN(&tp, BSSGP_IE_TMSI) >= 4)
		if (!pinfo->ptmsi)
			pinfo->ptmsi = talloc_zero_size(pinfo, sizeof(uint32_t));
		*(pinfo->ptmsi) = ntohl(*(uint32_t *)
					TLVP_VAL(&tp, BSSGP_IE_TMSI));

	return 0;

err_mand_ie:
err_cond_ie:
err:
	/* FIXME */
	return 0;
}
예제 #6
0
void gprs_gb_log_parse_context(int log_level,
			       struct gprs_gb_parse_context *parse_ctx,
			       const char *default_msg_name)
{
	const char *msg_name;
	const char *sep = "";

	if (!parse_ctx->tlli_enc &&
	    !parse_ctx->ptmsi_enc &&
	    !parse_ctx->new_ptmsi_enc &&
	    !parse_ctx->bssgp_ptmsi_enc &&
	    !parse_ctx->imsi)
		return;

	msg_name = gprs_gb_message_name(parse_ctx, default_msg_name);

	if (parse_ctx->llc_msg_name)
		msg_name = parse_ctx->llc_msg_name;

	LOGP(DGPRS, log_level, "%s: Got", msg_name);

	if (parse_ctx->tlli_enc) {
		LOGPC(DGPRS, log_level, "%s TLLI %08x", sep, parse_ctx->tlli);
		sep = ",";
	}

	if (parse_ctx->old_tlli_enc) {
		LOGPC(DGPRS, log_level, "%s old TLLI %02x%02x%02x%02x", sep,
		     parse_ctx->old_tlli_enc[0],
		     parse_ctx->old_tlli_enc[1],
		     parse_ctx->old_tlli_enc[2],
		     parse_ctx->old_tlli_enc[3]);
		sep = ",";
	}

	if (parse_ctx->bssgp_raid_enc) {
		struct gprs_ra_id raid;
		gsm48_parse_ra(&raid, parse_ctx->bssgp_raid_enc);
		LOGPC(DGPRS, log_level, "%s BSSGP RAID %u-%u-%u-%u", sep,
		     raid.mcc, raid.mnc, raid.lac, raid.rac);
		sep = ",";
	}

	if (parse_ctx->raid_enc) {
		struct gprs_ra_id raid;
		gsm48_parse_ra(&raid, parse_ctx->raid_enc);
		LOGPC(DGPRS, log_level, "%s RAID %u-%u-%u-%u", sep,
		     raid.mcc, raid.mnc, raid.lac, raid.rac);
		sep = ",";
	}

	if (parse_ctx->old_raid_enc) {
		struct gprs_ra_id raid;
		gsm48_parse_ra(&raid, parse_ctx->old_raid_enc);
		LOGPC(DGPRS, log_level, "%s old RAID %u-%u-%u-%u", sep,
		     raid.mcc, raid.mnc, raid.lac, raid.rac);
		sep = ",";
	}

	if (parse_ctx->bssgp_ptmsi_enc) {
		uint32_t ptmsi = GSM_RESERVED_TMSI;
		gprs_parse_tmsi(parse_ctx->bssgp_ptmsi_enc, &ptmsi);
		LOGPC(DGPRS, log_level, "%s BSSGP PTMSI %08x", sep, ptmsi);
		sep = ",";
	}

	if (parse_ctx->ptmsi_enc) {
		uint32_t ptmsi = GSM_RESERVED_TMSI;
		gprs_parse_tmsi(parse_ctx->ptmsi_enc, &ptmsi);
		LOGPC(DGPRS, log_level, "%s PTMSI %08x", sep, ptmsi);
		sep = ",";
	}

	if (parse_ctx->new_ptmsi_enc) {
		uint32_t new_ptmsi = GSM_RESERVED_TMSI;
		gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi);
		LOGPC(DGPRS, log_level, "%s new PTMSI %08x", sep, new_ptmsi);
		sep = ",";
	}

	if (parse_ctx->imsi) {
		char mi_buf[200];
		mi_buf[0] = '\0';
		gsm48_mi_to_string(mi_buf, sizeof(mi_buf),
				   parse_ctx->imsi, parse_ctx->imsi_len);
		LOGPC(DGPRS, log_level, "%s IMSI %s",
		     sep, mi_buf);
		sep = ",";
	}
	if (parse_ctx->invalidate_tlli) {
		LOGPC(DGPRS, log_level, "%s invalidate", sep);
		sep = ",";
	}
	if (parse_ctx->await_reattach) {
		LOGPC(DGPRS, log_level, "%s re-attach", sep);
		sep = ",";
	}

	LOGPC(DGPRS, log_level, "\n");
}