void sinsp_filter_check::parse_filter_value(const char* str, uint32_t len) { string_to_rawval(str, len, m_field->m_type); }
size_t sinsp_filter_value_parser::string_to_rawval(const char* str, uint32_t len, uint8_t *storage, string::size_type max_len, ppm_param_type ptype) { size_t parsed_len; switch(ptype) { case PT_INT8: *(int8_t*)storage = sinsp_numparser::parsed8(str); parsed_len = sizeof(int8_t); break; case PT_INT16: *(int16_t*)storage = sinsp_numparser::parsed16(str); parsed_len = sizeof(int16_t); break; case PT_INT32: *(int32_t*)storage = sinsp_numparser::parsed32(str); parsed_len = sizeof(int32_t); break; case PT_INT64: case PT_FD: case PT_ERRNO: *(int64_t*)storage = sinsp_numparser::parsed64(str); parsed_len = sizeof(int64_t); break; case PT_L4PROTO: // This can be resolved in the future case PT_FLAGS8: case PT_UINT8: *(uint8_t*)storage = sinsp_numparser::parseu8(str); parsed_len = sizeof(int8_t); break; case PT_PORT: { string in(str); if(in.empty()) { *(uint16_t*)storage = 0; } else { // if the string is made only of numbers if(strspn(in.c_str(), "0123456789") == in.size()) { *(uint16_t*)storage = stoi(in); } else { struct servent* se = getservbyname(in.c_str(), NULL); if(se == NULL) { throw sinsp_exception("unrecognized protocol " + in); } else { *(uint16_t*)storage = ntohs(getservbyname(in.c_str(), NULL)->s_port); } } } parsed_len = sizeof(int16_t); break; } case PT_FLAGS16: case PT_UINT16: *(uint16_t*)storage = sinsp_numparser::parseu16(str); parsed_len = sizeof(uint16_t); break; case PT_FLAGS32: case PT_UINT32: *(uint32_t*)storage = sinsp_numparser::parseu32(str); parsed_len = sizeof(uint32_t); break; case PT_UINT64: *(uint64_t*)storage = sinsp_numparser::parseu64(str); parsed_len = sizeof(uint64_t); break; case PT_RELTIME: case PT_ABSTIME: *(uint64_t*)storage = sinsp_numparser::parseu64(str); parsed_len = sizeof(uint64_t); break; case PT_CHARBUF: case PT_SOCKADDR: case PT_SOCKFAMILY: { len = (uint32_t)strlen(str); if(len >= max_len) { throw sinsp_exception("filter parameter too long:" + string(str)); } memcpy(storage, str, len); *(uint8_t*)(&storage[len]) = 0; parsed_len = len; } break; case PT_BOOL: parsed_len = sizeof(uint32_t); if(string(str) == "true") { *(uint32_t*)storage = 1; } else if(string(str) == "false") { *(uint32_t*)storage = 0; } else { throw sinsp_exception("filter error: unrecognized boolean value " + string(str)); } break; case PT_IPADDR: if(memchr(str, '.', len) != NULL) { return string_to_rawval(str, len, storage, max_len, PT_IPV4ADDR); } else { return string_to_rawval(str, len, storage, max_len, PT_IPV6ADDR); } break; case PT_IPV4ADDR: if(inet_pton(AF_INET, str, storage) != 1) { throw sinsp_exception("unrecognized IPv4 address " + string(str)); } parsed_len = sizeof(struct in_addr); break; case PT_IPV6ADDR: case PT_IPV6NET: { ipv6addr *addr = (ipv6addr*) storage; if(inet_pton(AF_INET6, str, addr->m_b) != 1) { throw sinsp_exception("unrecognized IPv6 address " + string(str)); } parsed_len = sizeof(ipv6addr); break; } case PT_IPNET: if(memchr(str, '.', len) != NULL) { return string_to_rawval(str, len, storage, max_len, PT_IPV4NET); } else { return string_to_rawval(str, len, storage, max_len, PT_IPV6NET); } break; case PT_IPV4NET: { stringstream ss(str); string ip, mask; ipv4net* net = (ipv4net*)storage; if (strchr(str, '/') == NULL) { throw sinsp_exception("unrecognized IP network " + string(str)); } getline(ss, ip, '/'); getline(ss, mask); if(inet_pton(AF_INET, ip.c_str(), &net->m_ip) != 1) { throw sinsp_exception("unrecognized IP address " + string(str)); } uint32_t cidrlen = sinsp_numparser::parseu8(mask); if (cidrlen > 32) { throw sinsp_exception("invalid netmask " + mask); } uint32_t j; net->m_netmask = 0; for(j = 0; j < cidrlen; j++) { net->m_netmask |= 1<<(31-j); } net->m_netmask = htonl(net->m_netmask); parsed_len = sizeof(ipv4net); break; } default: ASSERT(false); throw sinsp_exception("wrong parameter type " + to_string((long long) ptype)); } return parsed_len; }