void handle_mm(struct session_info *s, struct gsm48_hdr *dtap, unsigned dtap_len, uint32_t fn) { if (dtap_len < sizeof(struct gsm48_hdr)) { SET_MSG_INFO(s, "FAILED SANITY CHECKS (MM_LEN)"); return; } switch (dtap->msg_type & 0x3f) { case 0x01: session_reset(s, 1); s->started = 1; SET_MSG_INFO(s, "IMSI DETACH"); s->detach = 1; s->mo = 1; handle_detach(s, dtap->data); break; case 0x02: SET_MSG_INFO(s, "LOC UPD ACCEPT"); handle_loc_upd_acc(s, dtap->data, dtap_len - 2); break; case 0x04: SET_MSG_INFO(s, "LOC UPD REJECT cause=%d", dtap->data[0]); s->locupd = 1; s->lu_reject = 1; s->lu_rej_cause = dtap->data[0]; s->mo = 1; break; case 0x08: session_reset(s, 1); if (dtap_len < sizeof(struct gsm48_loc_upd_req)) { SET_MSG_INFO(s, "FAILED SANITY CHECKS (LUR_DTAP_SIZE)"); break; } SET_MSG_INFO(s, "LOC UPD REQUEST"); handle_loc_upd_req(s, dtap->data); break; case 0x12: if ((dtap_len > 19) && (dtap->data[17] == 0x20) && (dtap->data[18] == 0x10)) { SET_MSG_INFO(s, "AUTH REQUEST (UMTS)"); s->auth = 2; } else { SET_MSG_INFO(s, "AUTH REQUEST (GSM)"); s->auth = 1; } if (!s->auth_req_fn) { if (fn) { s->auth_req_fn = fn; } else { s->auth_req_fn = GSM_MAX_FN; } } break; case 0x14: if ((dtap_len > 6) && (dtap->data[4] == 0x21) && (dtap->data[5] == 0x04)) { SET_MSG_INFO(s, "AUTH RESPONSE (UMTS)"); if (!s->auth) { s->auth = 2; } } else { SET_MSG_INFO(s, "AUTH RESPONSE (GSM)"); if (!s->auth) { s->auth = 1; } } if (!s->auth_resp_fn) { if (fn) { s->auth_resp_fn = fn; } else { s->auth_resp_fn = GSM_MAX_FN; } } break; case 0x18: switch (dtap->data[0] & GSM_MI_TYPE_MASK) { case GSM_MI_TYPE_IMSI: SET_MSG_INFO(s, "IDENTITY REQUEST, IMSI"); if (s->cipher) { s->iden_imsi_ac = 1; } else { s->iden_imsi_bc = 1; } break; case GSM_MI_TYPE_IMEI: case GSM_MI_TYPE_IMEISV: SET_MSG_INFO(s, "IDENTITY REQUEST, IMEI"); if (s->cipher) { s->iden_imei_ac = 1; } else { s->iden_imei_bc = 1; } break; } break; case 0x19: handle_mi(s, &dtap->data[1], dtap->data[0], 0); switch (dtap->data[1] & GSM_MI_TYPE_MASK) { case GSM_MI_TYPE_IMSI: SET_MSG_INFO(s, "IDENTITY RESPONSE, IMSI %s", s->imsi); if (s->cipher) { s->iden_imsi_ac = 1; } else { s->iden_imsi_bc = 1; } break; case GSM_MI_TYPE_IMEI: case GSM_MI_TYPE_IMEISV: SET_MSG_INFO(s, "IDENTITY RESPONSE, IMEI %s", s->imei); if (s->cipher) { s->iden_imei_ac = 1; } else { s->iden_imei_bc = 1; } break; } break; case 0x1a: SET_MSG_INFO(s, "TMSI REALLOC COMMAND"); s->tmsi_realloc = 1; handle_lai(s, dtap->data, -1); handle_mi(s, &dtap->data[6], dtap->data[5], 1); break; case 0x1b: SET_MSG_INFO(s, "TMSI REALLOC COMPLETE"); s->tmsi_realloc = 1; break; case 0x21: SET_MSG_INFO(s, "CM SERVICE ACCEPT"); s->mo = 1; break; case 0x23: SET_MSG_INFO(s, "CM SERVICE ABORT"); s->mo = 1; break; case 0x24: SET_MSG_INFO(s, "CM SERVICE REQUEST"); session_reset(s, 1); s->started = 1; s->closed = 0; s->serv_req = 1; s->mo = 1; handle_cmreq(s, dtap->data); break; case 0x29: SET_MSG_INFO(s, "ABORT"); s->abort = 1; break; case 0x32: SET_MSG_INFO(s, "MM INFORMATION"); break; default: SET_MSG_INFO(s, "UNKNOWN MM (%02x)", dtap->msg_type & 0x3f); s->unknown = 1; } }
bool sys_ptrace( int sc_num, pid_t pid, pid_state *state ) { bool ret=true; if( state->state==pid_state::NONE ) { state->context_state[0]=ptlib_get_argument( pid, 1 ); // request state->context_state[1]=ptlib_get_argument( pid, 2 ); // pid state->context_state[2]=ptlib_get_argument( pid, 3 ); // addr state->context_state[3]=ptlib_get_argument( pid, 4 ); // data dlog("ptrace: " PID_F " ptrace( %d, " PID_F ", %p, %p )\n", pid, (int)state->context_state[0], (pid_t)state->context_state[1], (void*)state->context_state[2], (void*)state->context_state[3] ); ptlib_set_syscall( pid, PREF_NOP ); state->state=pid_state::REDIRECT2; } else if( state->state==pid_state::REDIRECT2 ) { state->state=pid_state::NONE; // Let's see what whether we need to succeed switch( state->context_state[0] ) { case PTRACE_TRACEME: if( begin_trace( state->parent, pid ) ) { dlog("ptrace: %d PTRACE_TRACEME parent " PID_F "\n", pid, state->parent ); ptlib_set_retval( pid, 0 ); } else { dlog("ptrace: %d PTRACE_TRACEME failed %s\n", pid, strerror(errno) ); ptlib_set_error( pid, state->orig_sc, errno ); } break; case PTRACE_ATTACH: if( begin_trace( pid, (pid_t)state->context_state[1] ) ) { dlog("ptrace: " PID_F " PTRACE_ATTACH(" PID_F ") succeeded\n", pid, (pid_t)state->context_state[1] ); ptlib_set_retval( pid, 0 ); } else { dlog("ptrace: " PID_F " PTRACE_ATTACH(" PID_F ") failed %s\n", pid, (pid_t)state->context_state[1], strerror(errno) ); ptlib_set_error( pid, state->orig_sc, errno ); } break; case PTRACE_PEEKTEXT: case PTRACE_PEEKDATA: #if HAVE_PTRACE_PEEKUSER case PTRACE_PEEKUSER: #endif handle_peek_data( pid, state ); break; case PTRACE_POKETEXT: case PTRACE_POKEDATA: #if HAVE_PTRACE_PEEKUSER case PTRACE_POKEUSER: #endif handle_poke_data( pid, state ); break; #if 0 case PTRACE_GETREGS: case PTRACE_GETFPREGS: dlog("ptrace: %d GETREGS not yet implemented\n", pid); ptlib_set_error( pid, state->orig_sc, EINVAL ); break; case PTRACE_SETREGS: case PTRACE_SETFPREGS: dlog("ptrace: %d SETREGS not yet implemented\n", pid); ptlib_set_error( pid, state->orig_sc, EINVAL ); break; case PTRACE_GETSIGINFO: dlog("ptrace: %d GETSIGINFO not yet implemented\n", pid); ptlib_set_error( pid, state->orig_sc, EINVAL ); break; case PTRACE_SETSIGINFO: dlog("ptrace: %d SETSIGINFO not yet implemented\n", pid); ptlib_set_error( pid, state->orig_sc, EINVAL ); break; #endif case PTRACE_SINGLESTEP: // We do not support single step right now ptlib_set_error( pid, state->orig_sc, EINVAL ); dlog("ptrace: " PID_F " tried to call SINGLESTEP on " PID_F "\n", pid, (pid_t)state->context_state[1]); break; case PTRACE_CONT: case PTRACE_SYSCALL: handle_cont_syscall( pid, state ); break; case PTRACE_KILL: handle_kill( pid, state ); break; case PTRACE_DETACH: handle_detach( pid, state ); break; default: dlog("ptrace: " PID_F " Unsupported option %lx\n", pid, state->context_state[0] ); ptlib_set_error(pid, state->orig_sc, EINVAL); break; } ptlib_set_syscall( pid, state->orig_sc ); } return ret; }