"Fossies" - the Fresh Open Source Software Archive

Member "sysdig-0.26.1/userspace/libsinsp/value_parser.cpp" (24 May 2019, 5220 Bytes) of package /linux/misc/sysdig-0.26.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "value_parser.cpp" see the Fossies "Dox" file reference documentation.

    1 /*
    2 Copyright (C) 2013-2018 Draios Inc dba Sysdig.
    3 
    4 This file is part of sysdig.
    5 
    6 Licensed under the Apache License, Version 2.0 (the "License");
    7 you may not use this file except in compliance with the License.
    8 You may obtain a copy of the License at
    9 
   10     http://www.apache.org/licenses/LICENSE-2.0
   11 
   12 Unless required by applicable law or agreed to in writing, software
   13 distributed under the License is distributed on an "AS IS" BASIS,
   14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   15 See the License for the specific language governing permissions and
   16 limitations under the License.
   17 
   18 */
   19 #include "sinsp.h"
   20 #include "sinsp_int.h"
   21 #include "value_parser.h"
   22 
   23 #ifdef _WIN32
   24 #pragma comment(lib, "Ws2_32.lib")
   25 #include <WinSock2.h>
   26 #else
   27 #include <netdb.h>
   28 #endif
   29 
   30 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)
   31 {
   32     size_t parsed_len;
   33 
   34     switch(ptype)
   35     {
   36         case PT_INT8:
   37             *(int8_t*)storage = sinsp_numparser::parsed8(str);
   38             parsed_len = sizeof(int8_t);
   39             break;
   40         case PT_INT16:
   41             *(int16_t*)storage = sinsp_numparser::parsed16(str);
   42             parsed_len = sizeof(int16_t);
   43             break;
   44         case PT_INT32:
   45             *(int32_t*)storage = sinsp_numparser::parsed32(str);
   46             parsed_len = sizeof(int32_t);
   47             break;
   48         case PT_INT64:
   49         case PT_FD:
   50         case PT_ERRNO:
   51             *(int64_t*)storage = sinsp_numparser::parsed64(str);
   52             parsed_len = sizeof(int64_t);
   53             break;
   54         case PT_L4PROTO: // This can be resolved in the future
   55         case PT_FLAGS8:
   56         case PT_UINT8:
   57             *(uint8_t*)storage = sinsp_numparser::parseu8(str);
   58             parsed_len = sizeof(int8_t);
   59             break;
   60         case PT_PORT:
   61         {
   62             string in(str);
   63 
   64             if(in.empty())
   65             {
   66                 *(uint16_t*)storage = 0;
   67             }
   68             else
   69             {
   70                 // if the string is made only of numbers
   71                 if(strspn(in.c_str(), "0123456789") == in.size())
   72                 {
   73                     *(uint16_t*)storage = stoi(in);
   74                 }
   75                 else
   76                 {
   77                     struct servent* se = getservbyname(in.c_str(), NULL);
   78 
   79                     if(se == NULL)
   80                     {
   81                         throw sinsp_exception("unrecognized protocol " + in);
   82                     }
   83                     else
   84                     {
   85                         *(uint16_t*)storage = ntohs(getservbyname(in.c_str(), NULL)->s_port);
   86                     }
   87                 }
   88             }
   89 
   90             parsed_len = sizeof(int16_t);
   91             break;
   92         }
   93         case PT_FLAGS16:
   94         case PT_UINT16:
   95             *(uint16_t*)storage = sinsp_numparser::parseu16(str);
   96             parsed_len = sizeof(uint16_t);
   97             break;
   98         case PT_FLAGS32:
   99         case PT_UINT32:
  100             *(uint32_t*)storage = sinsp_numparser::parseu32(str);
  101             parsed_len = sizeof(uint32_t);
  102             break;
  103         case PT_UINT64:
  104             *(uint64_t*)storage = sinsp_numparser::parseu64(str);
  105             parsed_len = sizeof(uint64_t);
  106             break;
  107         case PT_RELTIME:
  108         case PT_ABSTIME:
  109             *(uint64_t*)storage = sinsp_numparser::parseu64(str);
  110             parsed_len = sizeof(uint64_t);
  111             break;
  112         case PT_CHARBUF:
  113         case PT_SOCKADDR:
  114         case PT_SOCKFAMILY:
  115             {
  116                 len = (uint32_t)strlen(str);
  117                 if(len >= max_len)
  118                 {
  119                     throw sinsp_exception("filter parameter too long:" + string(str));
  120                 }
  121 
  122                 memcpy(storage, str, len);
  123                 *(uint8_t*)(&storage[len]) = 0;
  124                 parsed_len = len;
  125             }
  126             break;
  127         case PT_BOOL:
  128             parsed_len = sizeof(uint32_t);
  129             if(string(str) == "true")
  130             {
  131                 *(uint32_t*)storage = 1;
  132             }
  133             else if(string(str) == "false")
  134             {
  135                 *(uint32_t*)storage = 0;
  136             }
  137             else
  138             {
  139                 throw sinsp_exception("filter error: unrecognized boolean value " + string(str));
  140             }
  141 
  142             break;
  143         case PT_IPADDR:
  144             if(memchr(str, '.', len) != NULL)
  145             {
  146                 return string_to_rawval(str, len, storage, max_len, PT_IPV4ADDR);
  147             }
  148             else
  149             {
  150                 return string_to_rawval(str, len, storage, max_len, PT_IPV6ADDR);
  151             }
  152 
  153             break;
  154             case PT_IPV4ADDR:
  155             if(inet_pton(AF_INET, str, storage) != 1)
  156             {
  157                 throw sinsp_exception("unrecognized IPv4 address " + string(str));
  158             }
  159             parsed_len = sizeof(struct in_addr);
  160             break;
  161             case PT_IPV6ADDR:
  162             case PT_IPV6NET:
  163         {
  164             ipv6addr *addr = (ipv6addr*) storage;
  165             if(inet_pton(AF_INET6, str, addr->m_b) != 1)
  166             {
  167                 throw sinsp_exception("unrecognized IPv6 address " + string(str));
  168             }
  169             parsed_len = sizeof(ipv6addr);
  170             break;
  171         }
  172         case PT_IPNET:
  173             if(memchr(str, '.', len) != NULL)
  174             {
  175                 return string_to_rawval(str, len, storage, max_len, PT_IPV4NET);
  176             }
  177             else
  178             {
  179                 return string_to_rawval(str, len, storage, max_len, PT_IPV6NET);
  180             }
  181 
  182             break;
  183         case PT_IPV4NET:
  184         {
  185             stringstream ss(str);
  186             string ip, mask;
  187             ipv4net* net = (ipv4net*)storage;
  188 
  189             if (strchr(str, '/') == NULL)
  190             {
  191                 throw sinsp_exception("unrecognized IP network " + string(str));
  192             }
  193 
  194             getline(ss, ip, '/');
  195             getline(ss, mask);
  196 
  197             if(inet_pton(AF_INET, ip.c_str(), &net->m_ip) != 1)
  198             {
  199                 throw sinsp_exception("unrecognized IP address " + string(str));
  200             }
  201 
  202             uint32_t cidrlen = sinsp_numparser::parseu8(mask);
  203 
  204             if (cidrlen > 32)
  205             {
  206                 throw sinsp_exception("invalid netmask " + mask);
  207             }
  208 
  209             uint32_t j;
  210             net->m_netmask = 0;
  211 
  212             for(j = 0; j < cidrlen; j++)
  213             {
  214                 net->m_netmask |= 1<<(31-j);
  215             }
  216 
  217             net->m_netmask = htonl(net->m_netmask);
  218 
  219             parsed_len = sizeof(ipv4net);
  220             break;
  221         }
  222         default:
  223             ASSERT(false);
  224             throw sinsp_exception("wrong parameter type " + to_string((long long) ptype));
  225     }
  226 
  227     return parsed_len;
  228 }
  229