diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c
index 9551335..6e6b03b 100644
--- a/openbsc/src/gprs/gb_proxy.c
+++ b/openbsc/src/gprs/gb_proxy.c
@@ -462,8 +462,8 @@ static int gbproxy_imsi_acquisition(struct gbproxy_peer *peer,
 	if (link_info->imsi_acq_pending && link_info->imsi_len > 0) {
 		int is_ident_resp =
 			parse_ctx->g48_hdr &&
-			parse_ctx->g48_hdr->proto_discr == GSM48_PDISC_MM_GPRS &&
-			parse_ctx->g48_hdr->msg_type == GSM48_MT_GMM_ID_RESP;
+			gsm48_hdr_pdisc(parse_ctx->g48_hdr) == GSM48_PDISC_MM_GPRS &&
+			gsm48_hdr_msg_type(parse_ctx->g48_hdr) == GSM48_MT_GMM_ID_RESP;
 
 		/* The IMSI is now available */
 		gbproxy_flush_stored_messages(peer, msg, now, link_info,
diff --git a/openbsc/src/gprs/gprs_gb_parse.c b/openbsc/src/gprs/gprs_gb_parse.c
index 6096854..63ac902 100644
--- a/openbsc/src/gprs/gprs_gb_parse.c
+++ b/openbsc/src/gprs/gprs_gb_parse.c
@@ -329,17 +329,20 @@ int gprs_gb_parse_dtap(uint8_t *data, size_t data_len,
 		       struct gprs_gb_parse_context *parse_ctx)
 {
 	struct gsm48_hdr *g48h;
+	uint8_t pdisc;
+	uint8_t msg_type;
 
 	if (gprs_shift_v_fixed(&data, &data_len, sizeof(*g48h), (uint8_t **)&g48h) <= 0)
 		return 0;
 
 	parse_ctx->g48_hdr = g48h;
 
-	if ((g48h->proto_discr & 0x0f) != GSM48_PDISC_MM_GPRS &&
-	    (g48h->proto_discr & 0x0f) != GSM48_PDISC_SM_GPRS)
+	pdisc = gsm48_hdr_pdisc(g48h);
+	if (pdisc != GSM48_PDISC_MM_GPRS && pdisc != GSM48_PDISC_SM_GPRS)
 		return 1;
 
-	switch (g48h->msg_type) {
+	msg_type = gsm48_hdr_msg_type(g48h);
+	switch (msg_type) {
 	case GSM48_MT_GMM_ATTACH_REQ:
 		return gprs_gb_parse_gmm_attach_req(data, data_len, parse_ctx);
 
@@ -376,6 +379,10 @@ int gprs_gb_parse_dtap(uint8_t *data, size_t data_len,
 		break;
 
 	default:
+		LOGP(DLLC, LOGL_NOTICE,
+		     "Unknown GSM 04.08 message type 0x%02hhx for protocol"
+		     " discriminator 0x%02hhx.\n",
+		     msg_type, pdisc);
 		break;
 	};
 
diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c
index d93ba3f..9d94c24 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -2089,7 +2089,7 @@ int gsm0408_gprs_force_reattach(struct sgsn_mm_ctx *mmctx)
 int gsm0408_gprs_rcvmsg(struct msgb *msg, struct gprs_llc_llme *llme)
 {
 	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
-	uint8_t pdisc = gh->proto_discr & 0x0f;
+	uint8_t pdisc = gsm48_hdr_pdisc(gh);
 	struct sgsn_mm_ctx *mmctx;
 	struct gprs_ra_id ra_id;
 	int rc = -EINVAL;
diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c
index 504f044..e6d820d 100644
--- a/openbsc/src/libbsc/bsc_api.c
+++ b/openbsc/src/libbsc/bsc_api.c
@@ -563,6 +563,7 @@ static void dispatch_dtap(struct gsm_subscriber_connection *conn,
 	struct bsc_api *api = msg->lchan->ts->trx->bts->network->bsc_api;
 	struct gsm48_hdr *gh;
 	uint8_t pdisc;
+	uint8_t msg_type;
 	int rc;
 
 	if (msgb_l3len(msg) < sizeof(*gh)) {
@@ -571,7 +572,8 @@ static void dispatch_dtap(struct gsm_subscriber_connection *conn,
 	}
 
 	gh = msgb_l3(msg);
-	pdisc = gh->proto_discr & 0x0f;
+	pdisc = gsm48_hdr_pdisc(gh);
+	msg_type = gsm48_hdr_msg_type(gh);
 
 	/* the idea is to handle all RR messages here, and only hand
 	 * MM/CC/SMS-CP/LCS up to the MSC.  Some messages like PAGING
@@ -581,7 +583,7 @@ static void dispatch_dtap(struct gsm_subscriber_connection *conn,
 	 * will call api->compl_l3() for it */
 	switch (pdisc) {
 	case GSM48_PDISC_RR:
-		switch (gh->msg_type) {
+		switch (msg_type) {
 		case GSM48_MT_RR_GPRS_SUSP_REQ:
 			DEBUGP(DRR, "GRPS SUSPEND REQUEST\n");
 			break;
@@ -640,7 +642,7 @@ static void dispatch_dtap(struct gsm_subscriber_connection *conn,
 			 * messages, but we'd rather forward what we
 			 * don't know than drop it... */
 			LOGP(DRR, LOGL_NOTICE, "BSC: Passing unknown 04.08 "
-			     "RR message type 0x%02x to MSC\n", gh->msg_type);
+			     "RR message type 0x%02x to MSC\n", msg_type);
 			if (api->dtap)
 				api->dtap(conn, link_id, msg);
 		}
diff --git a/openbsc/src/libfilter/bsc_msg_filter.c b/openbsc/src/libfilter/bsc_msg_filter.c
index eafeff4..115d376 100644
--- a/openbsc/src/libfilter/bsc_msg_filter.c
+++ b/openbsc/src/libfilter/bsc_msg_filter.c
@@ -339,15 +339,15 @@ int bsc_msg_filter_initial(struct gsm48_hdr *hdr48, size_t hdr48_len,
 	cause->lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED;
 	*imsi = NULL;
 
-	proto = hdr48->proto_discr & 0x0f;
-	msg_type = hdr48->msg_type & 0xbf;
+	proto = gsm48_hdr_pdisc(hdr48);
+	msg_type = gsm48_hdr_msg_type(hdr48);
 	if (proto == GSM48_PDISC_MM &&
 	    msg_type == GSM48_MT_MM_LOC_UPD_REQUEST) {
 		*con_type = FLT_CON_TYPE_LU;
 		ret = _cr_check_loc_upd(req->ctx, &hdr48->data[0],
 					hdr48_len - sizeof(*hdr48), imsi);
 	} else if (proto == GSM48_PDISC_MM &&
-		  msg_type == GSM48_MT_MM_CM_SERV_REQ) {
+		   msg_type == GSM48_MT_MM_CM_SERV_REQ) {
 		*con_type = FLT_CON_TYPE_CM_SERV_REQ;
 		ret = _cr_check_cm_serv_req(req->ctx, &hdr48->data[0],
 					     hdr48_len - sizeof(*hdr48),
@@ -388,8 +388,8 @@ int bsc_msg_filter_data(struct gsm48_hdr *hdr48, size_t len,
 	if (state->imsi_checked)
 		return 0;
 
-	proto = hdr48->proto_discr & 0x0f;
-	msg_type = hdr48->msg_type & 0xbf;
+	proto = gsm48_hdr_pdisc(hdr48);
+	msg_type = gsm48_hdr_msg_type(hdr48);
 	if (proto != GSM48_PDISC_MM || msg_type != GSM48_MT_MM_ID_RESP)
 		return 0;
 
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index 47f3fa7..a1759f9 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -124,13 +124,12 @@ static int gsm48_conn_sendmsg(struct msgb *msg, struct gsm_subscriber_connection
 		msg->lchan = trans->conn->lchan;
 	}
 
-
 	if (msg->lchan) {
 		struct e1inp_sign_link *sign_link =
 				msg->lchan->ts->trx->rsl_link;
 
 		msg->dst = sign_link;
-		if ((gh->proto_discr & GSM48_PDISC_MASK) == GSM48_PDISC_CC)
+		if (gsm48_hdr_pdisc(gh) == GSM48_PDISC_CC)
 			DEBUGP(DCC, "(bts %d trx %d ts %d ti %02x) "
 				"Sending '%s' to MS.\n",
 				sign_link->trx->bts->nr,
@@ -1140,7 +1139,7 @@ static int gsm0408_rcv_mm(struct gsm_subscriber_connection *conn, struct msgb *m
 	struct gsm48_hdr *gh = msgb_l3(msg);
 	int rc = 0;
 
-	switch (gh->msg_type & 0xbf) {
+	switch (gsm48_hdr_msg_type(gh)) {
 	case GSM48_MT_MM_LOC_UPD_REQUEST:
 		DEBUGP(DMM, "LOCATION UPDATING REQUEST: ");
 		rc = mm_rx_loc_upd_req(conn, msg);
@@ -1869,7 +1868,7 @@ static void gsm48_start_cc_timer(struct gsm_trans *trans, int current,
 static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg)
 {
 	struct gsm48_hdr *gh = msgb_l3(msg);
-	uint8_t msg_type = gh->msg_type & 0xbf;
+	uint8_t msg_type = gsm48_hdr_msg_type(gh);
 	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
 	struct tlv_parsed tp;
 	struct gsm_mncc setup;
@@ -3496,7 +3495,7 @@ static struct datastate {
 static int gsm0408_rcv_cc(struct gsm_subscriber_connection *conn, struct msgb *msg)
 {
 	struct gsm48_hdr *gh = msgb_l3(msg);
-	uint8_t msg_type = gh->msg_type & 0xbf;
+	uint8_t msg_type = gsm48_hdr_msg_type(gh);
 	uint8_t transaction_id = ((gh->proto_discr & 0xf0) ^ 0x80) >> 4; /* flip */
 	struct gsm_trans *trans = NULL;
 	int i, rc = 0;
@@ -3587,7 +3586,7 @@ int gsm0408_new_conn(struct gsm_subscriber_connection *conn)
 int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg)
 {
 	struct gsm48_hdr *gh = msgb_l3(msg);
-	uint8_t pdisc = gh->proto_discr & 0x0f;
+	uint8_t pdisc = gsm48_hdr_pdisc(gh);
 	int rc = 0;
 
 	LOGP(DRLL, LOGL_DEBUG, "Dispatching 04.08 message, pdisc=%d\n", pdisc);
diff --git a/openbsc/src/libmsc/silent_call.c b/openbsc/src/libmsc/silent_call.c
index e9ece18..131a178 100644
--- a/openbsc/src/libmsc/silent_call.c
+++ b/openbsc/src/libmsc/silent_call.c
@@ -95,7 +95,8 @@ static const struct msg_match silent_call_accept[] = {
 int silent_call_reroute(struct gsm_subscriber_connection *conn, struct msgb *msg)
 {
 	struct gsm48_hdr *gh = msgb_l3(msg);
-	uint8_t pdisc = gh->proto_discr & 0x0f;
+	uint8_t pdisc = gsm48_hdr_pdisc(gh);
+	uint8_t msg_type = gsm48_hdr_msg_type(gh);
 	int i;
 
 	/* if we're not part of a silent call, never reroute */
@@ -105,7 +106,7 @@ int silent_call_reroute(struct gsm_subscriber_connection *conn, struct msgb *msg
 	/* check if we are a special message that is handled in openbsc */
 	for (i = 0; i < ARRAY_SIZE(silent_call_accept); i++) {
 		if (silent_call_accept[i].pdisc == pdisc &&
-		    silent_call_accept[i].msg_type == gh->msg_type)
+		    silent_call_accept[i].msg_type == msg_type)
 			return 0;
 	}
 
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_api.c b/openbsc/src/osmo-bsc/osmo_bsc_api.c
index fbeed77..d31e6c1 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_api.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_api.c
@@ -180,8 +180,8 @@ static void bsc_send_ussd_no_srv(struct gsm_subscriber_connection *conn,
 		return;
 
 	gh = msgb_l3(msg);
-	pdisc = gh->proto_discr & 0x0f;
-	mtype = gh->msg_type & 0xbf;
+	pdisc = gsm48_hdr_pdisc(gh);
+	mtype = gsm48_hdr_msg_type(gh);
 
 	/* Is CM service request? */
 	if (pdisc == GSM48_PDISC_MM && mtype == GSM48_MT_MM_CM_SERV_REQ) {
@@ -341,8 +341,8 @@ static int handle_cc_setup(struct gsm_subscriber_connection *conn,
 			   struct msgb *msg)
 {
 	struct gsm48_hdr *gh = msgb_l3(msg);
-	uint8_t pdisc = gh->proto_discr & 0x0f;
-	uint8_t mtype = gh->msg_type & 0xbf;
+	uint8_t pdisc = gsm48_hdr_pdisc(gh);
+	uint8_t mtype = gsm48_hdr_msg_type(gh);
 
 	struct osmo_msc_data *msc;
 	struct gsm_mncc_number called;
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_filter.c b/openbsc/src/osmo-bsc/osmo_bsc_filter.c
index 389a124..a71871f 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_filter.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_filter.c
@@ -141,8 +141,8 @@ struct osmo_msc_data *bsc_find_msc(struct gsm_subscriber_connection *conn,
 	}
 
 	gh = msgb_l3(msg);
-	pdisc = gh->proto_discr & 0x0f;
-	mtype = gh->msg_type & 0xbf;
+	pdisc = gsm48_hdr_pdisc(gh);
+	mtype = gsm48_hdr_msg_type(gh);
 
 	/*
 	 * We are asked to select a MSC here but they are not equal. We
@@ -212,8 +212,8 @@ paging:
 int bsc_scan_bts_msg(struct gsm_subscriber_connection *conn, struct msgb *msg)
 {
 	struct gsm48_hdr *gh = msgb_l3(msg);
-	uint8_t pdisc = gh->proto_discr & 0x0f;
-	uint8_t mtype = gh->msg_type & 0xbf;
+	uint8_t pdisc = gsm48_hdr_pdisc(gh);
+	uint8_t mtype = gsm48_hdr_msg_type(gh);
 
 	if (pdisc == GSM48_PDISC_MM) {
 		if (mtype == GSM48_MT_MM_LOC_UPD_REQUEST)
@@ -347,7 +347,7 @@ int bsc_scan_msc_msg(struct gsm_subscriber_connection *conn, struct msgb *msg)
 	gh = (struct gsm48_hdr *) msgb_l3(msg);
 	length -= (const char *)&gh->data[0] - (const char *)gh;
 
-	mtype = gh->msg_type & 0xbf;
+	mtype = gsm48_hdr_msg_type(gh);
 	net = conn->bts->network;
 	msc = conn->sccp_con->msc;
 
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c
index cdab406..cacb919 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c
@@ -670,8 +670,8 @@ static void update_con_authorize(struct nat_sccp_connection *con,
 		if (!hdr48)
 			return;
 
-		proto = hdr48->proto_discr & 0x0f;
-		msg_type = hdr48->msg_type & 0xbf;
+		proto = gsm48_hdr_pdisc(hdr48);
+		msg_type = gsm48_hdr_msg_type(hdr48);
 		if (proto == GSM48_PDISC_MM &&
 		    msg_type == GSM48_MT_MM_CM_SERV_ACC)
 			con->authorized = 1;
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c b/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c
index ca5670c..58667fe 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c
@@ -594,8 +594,8 @@ struct msgb *bsc_nat_rewrite_msg(struct bsc_nat *nat, struct msgb *msg, struct b
 		return msg;
 
 	link_id = msg->l3h[1];
-	proto = hdr48->proto_discr & 0x0f;
-	msg_type = hdr48->msg_type & 0xbf;
+	proto = gsm48_hdr_pdisc(hdr48);
+	msg_type = gsm48_hdr_msg_type(hdr48);
 
 	if (proto == GSM48_PDISC_CC && msg_type == GSM48_MT_CC_SETUP)
 		new_msg = rewrite_setup(nat, msg, parsed, imsi, hdr48, len);
diff --git a/openbsc/src/osmo-bsc_nat/bsc_ussd.c b/openbsc/src/osmo-bsc_nat/bsc_ussd.c
index 1082414..2905c85 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_ussd.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_ussd.c
@@ -407,8 +407,8 @@ int bsc_ussd_check(struct nat_sccp_connection *con, struct bsc_nat_parsed *parse
 	if (!hdr48)
 		return 0;
 
-	proto = hdr48->proto_discr & 0x0f;
-	msg_type = hdr48->msg_type & 0xbf;
+	proto = gsm48_hdr_pdisc(hdr48);
+	msg_type = gsm48_hdr_msg_type(hdr48);
 	ti = (hdr48->proto_discr & 0x70) >> 4;
 	if (proto != GSM48_PDISC_NC_SS)
 		return 0;
