uint8_t* sinsp_filter_check_fd::extract(sinsp_evt *evt, OUT uint32_t* len) { ASSERT(evt); if(!extract_fd(evt)) { return NULL; } // // TYPE_FDNUM doesn't need fdinfo // if(m_field_id == TYPE_FDNUM) { return (uint8_t*)&m_tinfo->m_lastevent_fd; } if(m_fdinfo == NULL) { return extract_from_null_fd(evt, len); } switch(m_field_id) { case TYPE_FDNAME: m_tstr = m_fdinfo->m_name; m_tstr.erase(remove_if(m_tstr.begin(), m_tstr.end(), g_invalidchar()), m_tstr.end()); return (uint8_t*)m_tstr.c_str(); case TYPE_FDTYPE: return extract_fdtype(m_fdinfo); case TYPE_DIRECTORY: { m_tstr = m_fdinfo->m_name; m_tstr.erase(remove_if(m_tstr.begin(), m_tstr.end(), g_invalidchar()), m_tstr.end()); size_t pos = m_tstr.rfind('/'); if(pos != string::npos) { if(pos < m_tstr.size() - 1) { m_tstr.resize(pos + 1); } } else { m_tstr = "/"; } return (uint8_t*)m_tstr.c_str(); } case TYPE_FDTYPECHAR: m_tcstr[0] = m_fdinfo->get_typechar(); m_tcstr[1] = 0; return m_tcstr; case TYPE_CLIENTIP: { scap_fd_type evt_type = m_fdinfo->m_type; if(m_fdinfo->is_role_none()) { return NULL; } if(evt_type == SCAP_FD_IPV4_SOCK) { return (uint8_t*)&(m_fdinfo->m_sockinfo.m_ipv4info.m_fields.m_sip); } } break; case TYPE_SERVERIP: { scap_fd_type evt_type = m_fdinfo->m_type; if(m_fdinfo->is_role_none()) { return NULL; } if(evt_type == SCAP_FD_IPV4_SOCK) { return (uint8_t*)&(m_fdinfo->m_sockinfo.m_ipv4info.m_fields.m_dip); } else if(evt_type == SCAP_FD_IPV4_SERVSOCK) { return (uint8_t*)&(m_fdinfo->m_sockinfo.m_ipv4serverinfo.m_ip); } } break; case TYPE_CLIENTPORT: { scap_fd_type evt_type = m_fdinfo->m_type; if(m_fdinfo->is_role_none()) { return NULL; } if(evt_type == SCAP_FD_IPV4_SOCK) { return (uint8_t*)&(m_fdinfo->m_sockinfo.m_ipv4info.m_fields.m_sport); } else if(evt_type == SCAP_FD_IPV6_SOCK) { return (uint8_t*)&(m_fdinfo->m_sockinfo.m_ipv6info.m_fields.m_sport); } } case TYPE_SERVERPORT: { scap_fd_type evt_type = m_fdinfo->m_type; if(evt_type == SCAP_FD_IPV4_SOCK) { if(m_fdinfo->is_role_none()) { return NULL; } return (uint8_t*)&(m_fdinfo->m_sockinfo.m_ipv4info.m_fields.m_dport); } else if(evt_type == SCAP_FD_IPV4_SERVSOCK) { return (uint8_t*)&(m_fdinfo->m_sockinfo.m_ipv4serverinfo.m_port); } else if(evt_type == SCAP_FD_IPV6_SOCK) { if(m_fdinfo->is_role_none()) { return NULL; } return (uint8_t*)&(m_fdinfo->m_sockinfo.m_ipv6info.m_fields.m_dport); } else if(evt_type == SCAP_FD_IPV6_SERVSOCK) { return (uint8_t*)&(m_fdinfo->m_sockinfo.m_ipv6serverinfo.m_port); } else { return NULL; } } case TYPE_L4PROTO: { scap_l4_proto l4p = m_fdinfo->get_l4proto(); switch(l4p) { case SCAP_L4_TCP: m_tstr = "tcp"; break; case SCAP_L4_UDP: m_tstr = "udp"; break; case SCAP_L4_ICMP: m_tstr = "icmp"; break; case SCAP_L4_RAW: m_tstr = "raw"; break; default: m_tstr = "<NA>"; break; } return (uint8_t*)m_tstr.c_str(); } case TYPE_IS_SERVER: { m_tbool = m_inspector->get_ifaddr_list()->is_ipv4addr_in_local_machine(m_fdinfo->m_sockinfo.m_ipv4info.m_fields.m_dip); return (uint8_t*)&m_tbool; } break; default: ASSERT(false); } return NULL; }
bool sinsp_filter_check_fd::extract_fdname_from_creator(sinsp_evt *evt, OUT uint32_t* len) { const char* resolved_argstr; uint16_t etype = evt->get_type(); if(PPME_IS_ENTER(etype)) { return false; } switch(etype) { case PPME_SYSCALL_OPEN_X: case PPME_SOCKET_ACCEPT_X: case PPME_SOCKET_ACCEPT4_X: case PPME_SYSCALL_CREAT_X: { const char* argstr = evt->get_param_as_str(1, &resolved_argstr, m_inspector->get_buffer_format()); if(resolved_argstr[0] != 0) { m_tstr = resolved_argstr; } else { m_tstr = argstr; } return true; } case PPME_SYSCALL_OPENAT_X: { // // XXX This is highly inefficient, as it re-requests the enter event and then // does unnecessary allocations and copies. We assume that failed openat() happen // rarely enough that we don't care. // sinsp_evt enter_evt; if(!m_inspector->get_parser()->retrieve_enter_event(&enter_evt, evt)) { return false; } sinsp_evt_param *parinfo; char *name; uint32_t namelen; string sdir; parinfo = enter_evt.get_param(1); name = parinfo->m_val; namelen = parinfo->m_len; parinfo = enter_evt.get_param(0); ASSERT(parinfo->m_len == sizeof(int64_t)); int64_t dirfd = *(int64_t *)parinfo->m_val; sinsp_parser::parse_openat_dir(evt, name, dirfd, &sdir); char fullpath[SCAP_MAX_PATH_SIZE]; sinsp_utils::concatenate_paths(fullpath, SCAP_MAX_PATH_SIZE, sdir.c_str(), sdir.length(), name, namelen); m_tstr = fullpath; m_tstr.erase(remove_if(m_tstr.begin(), m_tstr.end(), g_invalidchar()), m_tstr.end()); return true; } default: m_tstr = ""; return true; } }
uint8_t* sinsp_filter_check_fd::extract_from_null_fd(sinsp_evt *evt, OUT uint32_t* len) { // // Even is there's no fd, we still try to extract a name from exit events that create // one. With these events, the fact that there's no FD means that the call failed, // but even if that happened we still want to collect the name. // switch(m_field_id) { case TYPE_FDNAME: { if(extract_fdname_from_creator(evt, len) == true) { return (uint8_t*)m_tstr.c_str(); } else { return NULL; } } case TYPE_DIRECTORY: { if(extract_fdname_from_creator(evt, len) == true) { m_tstr.erase(remove_if(m_tstr.begin(), m_tstr.end(), g_invalidchar()), m_tstr.end()); size_t pos = m_tstr.rfind('/'); if(pos != string::npos) { if(pos < m_tstr.size() - 1) { m_tstr.resize(pos + 1); } } else { m_tstr = "/"; } return (uint8_t*)m_tstr.c_str(); } else { return NULL; } } case TYPE_FDTYPECHAR: switch(PPME_MAKE_ENTER(evt->get_type())) { case PPME_SYSCALL_OPEN_E: case PPME_SYSCALL_OPENAT_E: case PPME_SYSCALL_CREAT_E: m_tcstr[0] = CHAR_FD_FILE; m_tcstr[1] = 0; return m_tcstr; case PPME_SOCKET_SOCKET_E: case PPME_SOCKET_ACCEPT_E: case PPME_SOCKET_ACCEPT4_E: // // Note, this is not accurate, because it always // returns IPv4 even if this could be IPv6 or unix. // For the moment, I assume it's better than nothing, and doing // real event parsing here would be a pain. // m_tcstr[0] = CHAR_FD_IPV4_SOCK; m_tcstr[1] = 0; return m_tcstr; case PPME_SYSCALL_PIPE_E: m_tcstr[0] = CHAR_FD_FIFO; m_tcstr[1] = 0; return m_tcstr; case PPME_SYSCALL_EVENTFD_E: m_tcstr[0] = CHAR_FD_EVENT; m_tcstr[1] = 0; return m_tcstr; case PPME_SYSCALL_SIGNALFD_E: m_tcstr[0] = CHAR_FD_SIGNAL; m_tcstr[1] = 0; return m_tcstr; case PPME_SYSCALL_TIMERFD_CREATE_E: m_tcstr[0] = CHAR_FD_TIMERFD; m_tcstr[1] = 0; return m_tcstr; case PPME_SYSCALL_INOTIFY_INIT_E: m_tcstr[0] = CHAR_FD_INOTIFY; m_tcstr[1] = 0; return m_tcstr; default: m_tcstr[0] = 'o'; m_tcstr[1] = 0; return m_tcstr; } default: return NULL; } }
template<> string sinsp_fdinfo_t::tostring_clean() { string m_tstr = m_name; m_tstr.erase(remove_if(m_tstr.begin(), m_tstr.end(), g_invalidchar()), m_tstr.end()); return m_tstr; }