NAS层代码审计笔记

UE部分

UE部分的代码和COMMOM部分的结构基本一致,按EMM和ESM两部分信令进行分类,每个EMM和ESM文件夹中又分为若干个源文件,里面包含了若干个信令的具体实现。下面是一些对研究可能有帮助的文件。

EMM/SAP/emm_send.c

emm_send.c部分包含以下函数,每个函数的返回值基本都是消息的大小(size)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/*
* --------------------------------------------------------------------------
* Functions executed by both the UE and the MME to send EMM messages
* --------------------------------------------------------------------------
*/
int emm_send_status(const emm_as_status_t *, emm_status_msg *);

int emm_send_detach_accept(const emm_as_data_t *, detach_accept_msg *);

/*
* --------------------------------------------------------------------------
* Functions executed by the UE to send EMM messages to the network
* --------------------------------------------------------------------------
*/
int emm_send_attach_request(const emm_as_establish_t *, attach_request_msg *);
int emm_send_attach_complete(const emm_as_data_t *, attach_complete_msg *);
int emm_send_initial_detach_request(const emm_as_establish_t *,
detach_request_msg *);
int emm_send_detach_request(const emm_as_data_t *, detach_request_msg *);
int emm_send_initial_tau_request(const emm_as_establish_t *,
tracking_area_update_request_msg *);
int emm_send_initial_sr_request(const emm_as_establish_t *,
service_request_msg *);
int emm_send_initial_extsr_request(const emm_as_establish_t *,
extended_service_request_msg *);
int emm_send_identity_response(const emm_as_security_t *,
identity_response_msg *);
int emm_send_authentication_response(const emm_as_security_t *,
authentication_response_msg *);
int emm_send_authentication_failure(const emm_as_security_t *,
authentication_failure_msg *);
int emm_send_security_mode_complete(const emm_as_security_t *,
security_mode_complete_msg *);
int emm_send_security_mode_reject(const emm_as_security_t *,
security_mode_reject_msg *);

各个函数的作用如下:

int emm_send_status(const emm_as_status_t *, emm_status_msg *);

用于UE或者网络在任意时刻报告错误状态,具体的状态在COMMON/EMM/MSG/emm_cause.h中有定义,下面是几个例子。

1
2
3
#define EMM_CAUSE_IMEI_NOT_ACCEPTED   5
#define EMM_CAUSE_EPS_NOT_ALLOWED 7
#define EMM_CAUSE_BOTH_NOT_ALLOWED 8

int emm_send_detach_accept(const emm_as_data_t *, detach_accept_msg *);

该函数用于告知detach过程已经完成了。

int emm_send_attach_request(const emm_as_establish_t *, attach_request_msg *);

UE向网络发送附着请求相关的信息。大致过程为:

  • 打印信息,表明当前正在进行Attach Request
  • 设置emm消息类型为ATTACH_REQUEST
  • 设置EPS附着类型
  • 设置密钥
  • 设置EPS移动标识:GUTI、IMSI和IMEI等
  • 设置UE网络能力相关参数
  • 设置ESM message container为NAS消息
  • 设置Last visited registered TAI(可选项)
  • 设置Old GUTI type(可选项)

int emm_send_attach_complete(const emm_as_data_t *, attach_complete_msg *);

UE对网络进行响应,发送一个Attach Accept信息。

int emm_send_initial_detach_request(const emm_as_establish_t *,detach_request_msg *);

UE请求释放EMM文本

COMMOM部分

常用的数据结构

1
2
3
4
5
6
typedef struct emm_as_status_s {
uint32_t ueid; /* UE lower layer identifier */
const GUTI_t *guti; /* GUTI temporary mobile identity */
emm_as_security_data_t sctx;/* EPS NAS security context */
int emm_cause; /* EMM failure cause code */
} emm_as_status_t;