"Fossies" - the Fresh Open Source Software Archive

Member "sysdig-0.26.1/userspace/libscap/examples/02-validatebuffer/test.c" (24 May 2019, 6412 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.

    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 
   20 #include <stdio.h>
   21 #include <stdlib.h>
   22 #include <sys/types.h>
   23 #include <unistd.h>
   24 #include <assert.h>
   25 
   26 #include <scap.h>
   27 #include "../../../../driver/ppm_events_public.h"
   28 
   29 extern const struct ppm_event_info g_event_info[];
   30 
   31 
   32 size_t g_get_event_size(enum ppm_event_type event_type, uint16_t* lens)
   33 {
   34     uint32_t j;
   35     int32_t res = 0;
   36 
   37     for(j = 0; j < g_event_info[event_type].nparams; j++)
   38     {
   39         res += lens[j];
   40     }
   41 
   42 #ifdef PPM_ENABLE_SENTINEL
   43     return res + j * sizeof(uint16_t) + sizeof(struct ppm_evt_hdr) + sizeof(uint32_t);
   44 #else
   45     return res + j * sizeof(uint16_t) + sizeof(struct ppm_evt_hdr);
   46 #endif
   47 }
   48 
   49 int32_t g_check_integrity(uint32_t* cur_event, char* copy_buffer, int buf_len, OUT uint32_t* nevents)
   50 {
   51     uint32_t offset = 0;
   52     *nevents = 0;
   53 
   54     while(buf_len)
   55     {
   56 #ifdef PPM_ENABLE_SENTINEL
   57         uint32_t sentinel_begin;
   58         uint32_t sentinel_end;
   59 #endif
   60         struct ppm_evt_hdr* hdr;
   61         size_t event_size;
   62 
   63         if(buf_len < sizeof(struct ppm_evt_hdr))
   64         {
   65             fprintf(stderr, "Error: event not on buffer boundary, offset %x, data to read %d\n",
   66                     offset,
   67                     buf_len);
   68             return SCAP_FAILURE;
   69         }
   70 
   71         hdr = (struct ppm_evt_hdr*)(copy_buffer + offset);
   72 
   73         uint16_t type = hdr->type;
   74         if(buf_len < sizeof(struct ppm_evt_hdr) + g_event_info[type].nparams * sizeof(uint16_t))
   75         {
   76             fprintf(stderr, "Error: event not on buffer boundary, offset %x, data to read %d\n",
   77                     offset,
   78                     buf_len);
   79             return SCAP_FAILURE;
   80         }
   81 
   82         event_size = g_get_event_size(hdr->type, (uint16_t*)(copy_buffer + offset + sizeof(struct ppm_evt_hdr)));
   83 
   84         if(event_size == -1)
   85         {
   86             fprintf(stderr, "Error: unrecognized event %u, cnt %u, offset %x\n",
   87                     (uint32_t)(hdr->type),
   88                     (*cur_event == -1)?0:*cur_event,
   89                     offset);
   90             return SCAP_FAILURE;
   91         }
   92 
   93         if(event_size < sizeof(struct ppm_evt_hdr) + g_event_info[hdr->type].nparams * sizeof(uint16_t))
   94         {
   95             fprintf(stderr, "Error: event size too short %u, cnt %u, offset %x\n",
   96                     (unsigned int)event_size,
   97                     (*cur_event == -1)?0:*cur_event,
   98                     offset);
   99             return SCAP_FAILURE;
  100         }
  101 
  102 #ifdef PPM_ENABLE_SENTINEL
  103         sentinel_begin = ((struct ppm_evt_hdr*)(copy_buffer + offset))->sentinel_begin;
  104         sentinel_end = *(uint32_t*)(copy_buffer + offset + event_size - sizeof(uint32_t));
  105 
  106         if(sentinel_begin != sentinel_end)
  107         {
  108             fprintf(stderr, "Error: sentinel begin %d, sentinel end %d, evt_type %u, evt_size %zu, cnt %u, offset %x, remaining %u\n",
  109                     sentinel_begin,
  110                     sentinel_end,
  111                     (uint32_t)hdr->type,
  112                     event_size,
  113                     (*cur_event == -1)?0:*cur_event,
  114                     offset,
  115                     buf_len);
  116             return SCAP_FAILURE;
  117         }
  118 
  119         if(*cur_event == -1)
  120         {
  121             *cur_event = sentinel_begin;
  122         }
  123 
  124         if(sentinel_begin != *cur_event)
  125         {
  126             fprintf(stderr, "Error1: sentinel begin %d, sentinel end %d, cnt %u, offset %x, remaining %u\n",
  127                     sentinel_begin,
  128                     sentinel_end,
  129                     *cur_event,
  130                     offset,
  131                     buf_len);
  132             return SCAP_FAILURE;
  133         }
  134 #endif
  135 
  136         buf_len -= event_size;
  137         offset += event_size;
  138 
  139         ++(*nevents);
  140         ++(*cur_event);
  141     }
  142 
  143     return 0;
  144 }
  145 
  146 int main()
  147 {
  148     uint32_t j;
  149     char error[SCAP_LASTERR_SIZE];
  150     int32_t ret;
  151     char* buf;
  152     uint32_t buflen;
  153     uint32_t cur_evts[256];
  154     int32_t ndevs;
  155     uint32_t nloops = 0;
  156     uint64_t totbytes = 0;
  157     uint64_t totevents = 0;
  158     uint64_t devicebytes[256];
  159     uint64_t deviceevents[256];
  160     uint64_t oldtotbytes = 0;
  161     uint64_t oldtotevents = 0;
  162     uint64_t olddevicebytes[256];
  163     uint64_t olddeviceevents[256];
  164 
  165     /*
  166         unsigned long new_mask = 1 << (1);
  167         sched_setaffinity(0,
  168             sizeof(unsigned long),
  169             &new_mask);
  170     */
  171 
  172     scap_t* h = scap_open_live(error, &ret);
  173     if(h == NULL)
  174     {
  175         fprintf(stderr, "%s (%d)\n", error, ret);
  176         return ret;
  177     }
  178 
  179     ndevs = scap_get_ndevs(h);
  180 
  181     if(ndevs > sizeof(cur_evts)/sizeof(cur_evts[0]))
  182     {
  183         fprintf(stderr, "too many devices %u\n", ndevs);
  184         return -1;
  185     }
  186 
  187     for(j = 0; j < ndevs; j++)
  188     {
  189         devicebytes[j] = 0;
  190         deviceevents[j] = 0;
  191         olddevicebytes[j] = 0;
  192         olddeviceevents[j] = 0;
  193     }
  194 
  195     while(1)
  196     {
  197         for(j = 0; j < ndevs; j++)
  198         {
  199             uint32_t nevents;
  200 
  201             ret = scap_readbuf(h, j, &buf, &buflen);
  202 
  203             if(ret != SCAP_SUCCESS)
  204             {
  205                 fprintf(stderr, "%s\n", scap_getlasterr(h));
  206                 scap_close(h);
  207                 return -1;
  208             }
  209 
  210             cur_evts[j] = -1;
  211 
  212             if(g_check_integrity(&(cur_evts[j]), buf, buflen, &nevents) != SCAP_SUCCESS)
  213             {
  214                 fprintf(stderr, "Integrity check failure at event %u.\nDumping buffer to dump.bin\n",
  215                         (cur_evts[j] == -1)?0:cur_evts[j]);
  216 
  217                 FILE* f;
  218                 f= fopen("dump.bin", "w");
  219                 fwrite(buf, buflen, 1, f);
  220                 fclose(f);
  221                 exit(-1);
  222             }
  223 
  224             totbytes += buflen;
  225             totevents += nevents;
  226             devicebytes[j] += buflen;
  227             deviceevents[j] += nevents;
  228 
  229             if(nloops == 1000)
  230             {
  231                 printf(" %u)bps:%" PRIu64 " totbytes:%" PRIu64 " - evts/s:%" PRIu64 " totevs:%" PRIu64 " \n",
  232                        j,
  233                        (devicebytes[j] - olddevicebytes[j]),
  234                        devicebytes[j],
  235                        (deviceevents[j] - olddeviceevents[j]),
  236                        deviceevents[j]);
  237 
  238                 olddevicebytes[j] = devicebytes[j];
  239                 olddeviceevents[j] = deviceevents[j];
  240             }
  241         }
  242 
  243         //
  244         // XXX this should check the buffer sizes and sleep only if they are all below a certain
  245         // threshold.
  246         //
  247         usleep(1000);
  248 
  249         if(nloops == 1000)
  250         {
  251             scap_stats stats;
  252 
  253             if(scap_get_stats(h, &stats) != SCAP_SUCCESS)
  254             {
  255                 fprintf(stderr, "%s\n", scap_getlasterr(h));
  256                 scap_close(h);
  257                 return -1;
  258             }
  259 
  260             printf("bps:%" PRIu64 " totbytes:%" PRIu64 " - evts/s:%" PRIu64 " totevs:%" PRIu64 " drops:%" PRIu64 "\n",
  261                    totbytes - oldtotbytes,
  262                    totbytes,
  263                    totevents - oldtotevents,
  264                    totevents,
  265                    stats.n_drops);
  266 
  267             oldtotbytes = totbytes;
  268             oldtotevents = totevents;
  269 
  270             nloops = 0;
  271         }
  272 
  273         nloops++;
  274     }
  275 
  276     scap_close(h);
  277     return 0;
  278 }