void sinsp::close() { if(m_h) { scap_close(m_h); m_h = NULL; } if(NULL != m_dumper) { scap_dump_close(m_dumper); m_dumper = NULL; } if(NULL != m_network_interfaces) { delete m_network_interfaces; m_network_interfaces = NULL; } #ifdef HAS_FILTERING if(m_filter != NULL) { delete m_filter; m_filter = NULL; } #endif }
scap_t* scap_open_live(char *error) { #if !defined(HAS_CAPTURE) snprintf(error, SCAP_LASTERR_SIZE, "live capture not supported on %s", PLATFORM_NAME); return NULL; #else uint32_t j; char dev[255]; scap_t* handle = NULL; int len; uint32_t ndevs; uint32_t res; // // Allocate the handle // handle = (scap_t*)malloc(sizeof(scap_t)); if(!handle) { snprintf(error, SCAP_LASTERR_SIZE, "error allocating the scap_t structure"); return NULL; } // // Preliminary initializations // handle->m_ndevs = 0; handle->m_proclist = NULL; handle->m_file = NULL; handle->m_file_evt_buf = NULL; handle->m_evtcnt = 0; handle->m_addrlist = NULL; handle->m_userlist = NULL; handle->m_emptybuf_timeout_ms = BUFFER_EMPTY_WAIT_TIME_MS; // // Find out how many devices we have to open, which equals to the number of CPUs // ndevs = sysconf(_SC_NPROCESSORS_ONLN); // // Allocate the device descriptors. // len = RING_BUF_SIZE * 2; handle->m_devs = (scap_device*)malloc(ndevs * sizeof(scap_device)); if(!handle->m_devs) { scap_close(handle); snprintf(error, SCAP_LASTERR_SIZE, "error allocating the device handles"); return NULL; } // // Allocate the array of poll fds. // handle->m_pollfds = (struct pollfd*)malloc(ndevs * sizeof(struct pollfd)); if(!handle->m_pollfds) { scap_close(handle); snprintf(error, SCAP_LASTERR_SIZE, "error allocating the device handles"); return NULL; } for(j = 0; j < ndevs; j++) { handle->m_devs[j].m_buffer = (char*)MAP_FAILED; handle->m_devs[j].m_bufinfo = (struct ppm_ring_buffer_info*)MAP_FAILED; } handle->m_ndevs = ndevs; // // Extract machine information // handle->m_machine_info.num_cpus = sysconf(_SC_NPROCESSORS_ONLN); handle->m_machine_info.memory_size_bytes = (uint64_t)sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE); gethostname(handle->m_machine_info.hostname, sizeof(handle->m_machine_info.hostname) / sizeof(handle->m_machine_info.hostname[0])); handle->m_machine_info.reserved1 = 0; handle->m_machine_info.reserved2 = 0; handle->m_machine_info.reserved3 = 0; handle->m_machine_info.reserved4 = 0; // // Create the interface list // if(scap_create_iflist(handle) != SCAP_SUCCESS) { scap_close(handle); snprintf(error, SCAP_LASTERR_SIZE, "error creating the interface list"); return NULL; } // // Create the user list // if(scap_create_userlist(handle) != SCAP_SUCCESS) { scap_close(handle); snprintf(error, SCAP_LASTERR_SIZE, "error creating the interface list"); return NULL; } // // Create the process list // error[0] = '\0'; if((res = scap_proc_scan_proc_dir(handle, "/proc", -1, -1, NULL, error, true)) != SCAP_SUCCESS) { scap_close(handle); snprintf(error, SCAP_LASTERR_SIZE, "error creating the process list. Make sure you have root credentials."); return NULL; } handle->m_fake_kernel_proc.tid = -1; handle->m_fake_kernel_proc.pid = -1; handle->m_fake_kernel_proc.flags = 0; snprintf(handle->m_fake_kernel_proc.comm, SCAP_MAX_PATH_SIZE, "kernel"); snprintf(handle->m_fake_kernel_proc.exe, SCAP_MAX_PATH_SIZE, "kernel"); handle->m_fake_kernel_proc.args[0] = 0; // // Open and initialize all the devices // for(j = 0; j < handle->m_ndevs; j++) { // // Open the device // sprintf(dev, "/dev/sysdig%d", j); if((handle->m_devs[j].m_fd = open(dev, O_RDWR | O_SYNC)) < 0) { if(errno == EBUSY) { snprintf(error, SCAP_LASTERR_SIZE, "device %s is already open. You can't run multiple instances of sysdig.", dev); } else { snprintf(error, SCAP_LASTERR_SIZE, "error opening device %s. Make sure you have root credentials and that the sysdig-probe module is loaded.", dev); } scap_close(handle); return NULL; } // // Init the polling fd for the device // handle->m_pollfds[j].fd = handle->m_devs[j].m_fd; handle->m_pollfds[j].events = POLLIN; // // Map the ring buffer // handle->m_devs[j].m_buffer = (char*)mmap(0, len, PROT_READ, MAP_SHARED, handle->m_devs[j].m_fd, 0); if(handle->m_devs[j].m_buffer == MAP_FAILED) { // we cleanup this fd and then we let scap_close() take care of the other ones close(handle->m_devs[j].m_fd); scap_close(handle); snprintf(error, SCAP_LASTERR_SIZE, "error mapping the ring buffer for device %s", dev); return NULL; } // // Map the ppm_ring_buffer_info that contains the buffer pointers // handle->m_devs[j].m_bufinfo = (struct ppm_ring_buffer_info*)mmap(0, sizeof(struct ppm_ring_buffer_info), PROT_READ | PROT_WRITE, MAP_SHARED, handle->m_devs[j].m_fd, 0); if(handle->m_devs[j].m_bufinfo == MAP_FAILED) { // we cleanup this fd and then we let scap_close() take care of the other ones munmap(handle->m_devs[j].m_buffer, len); close(handle->m_devs[j].m_fd); scap_close(handle); snprintf(error, SCAP_LASTERR_SIZE, "error mapping the ring buffer info for device %s", dev); return NULL; } // // Additional initializations // handle->m_devs[j].m_lastreadsize = 0; handle->m_devs[j].m_sn_len = 0; scap_stop_dropping_mode(handle); } return handle; #endif // HAS_CAPTURE }
scap_t* scap_open_offline(const char* fname, char *error) { scap_t* handle = NULL; // // Allocate the handle // handle = (scap_t*)malloc(sizeof(scap_t)); if(!handle) { snprintf(error, SCAP_LASTERR_SIZE, "error allocating the scap_t structure"); return NULL; } // // Preliminary initializations // handle->m_devs = NULL; handle->m_ndevs = 0; handle->m_proclist = NULL; handle->m_pollfds = NULL; handle->m_evtcnt = 0; handle->m_file = NULL; handle->m_addrlist = NULL; handle->m_userlist = NULL; handle->m_machine_info.num_cpus = (uint32_t)-1; handle->m_file_evt_buf = (char*)malloc(FILE_READ_BUF_SIZE); if(!handle->m_file_evt_buf) { snprintf(error, SCAP_LASTERR_SIZE, "error allocating the read buffer"); scap_close(handle); return NULL; } // // Open the file // handle->m_file = gzopen(fname, "rb"); if(handle->m_file == NULL) { snprintf(error, SCAP_LASTERR_SIZE, "can't open file %s", fname); scap_close(handle); return NULL; } // // Validate the file and load the non-event blocks // if(scap_read_init(handle, handle->m_file) != SCAP_SUCCESS) { snprintf(error, SCAP_LASTERR_SIZE, "%s", scap_getlasterr(handle)); scap_close(handle); return NULL; } // // Add the fake process for kernel threads // handle->m_fake_kernel_proc.tid = -1; handle->m_fake_kernel_proc.pid = -1; handle->m_fake_kernel_proc.flags = 0; snprintf(handle->m_fake_kernel_proc.comm, SCAP_MAX_PATH_SIZE, "kernel"); snprintf(handle->m_fake_kernel_proc.exe, SCAP_MAX_PATH_SIZE, "kernel"); handle->m_fake_kernel_proc.args[0] = 0; //scap_proc_print_table(handle); return handle; }
int main() { uint32_t j; char error[SCAP_LASTERR_SIZE]; int32_t ret; char* buf; uint32_t buflen; uint32_t cur_evts[256]; int32_t ndevs; uint32_t nloops = 0; uint64_t totbytes = 0; uint64_t totevents = 0; uint64_t devicebytes[256]; uint64_t deviceevents[256]; uint64_t oldtotbytes = 0; uint64_t oldtotevents = 0; uint64_t olddevicebytes[256]; uint64_t olddeviceevents[256]; /* unsigned long new_mask = 1 << (1); sched_setaffinity(0, sizeof(unsigned long), &new_mask); */ scap_t* h = scap_open_live(error); if(h == NULL) { fprintf(stderr, "%s\n", error); return -1; } ndevs = scap_get_ndevs(h); if(ndevs > sizeof(cur_evts)/sizeof(cur_evts[0])) { fprintf(stderr, "too many devices %u\n", ndevs); return -1; } for(j = 0; j < ndevs; j++) { devicebytes[j] = 0; deviceevents[j] = 0; olddevicebytes[j] = 0; olddeviceevents[j] = 0; } while(1) { for(j = 0; j < ndevs; j++) { uint32_t nevents; ret = scap_readbuf(h, j, false, &buf, &buflen); if(ret != SCAP_SUCCESS) { fprintf(stderr, "%s\n", scap_getlasterr(h)); scap_close(h); return -1; } cur_evts[j] = -1; if(g_check_integrity(&(cur_evts[j]), buf, buflen, &nevents) != SCAP_SUCCESS) { fprintf(stderr, "Integrity check failure at event %u.\nDumping buffer to dump.bin\n", (cur_evts[j] == -1)?0:cur_evts[j]); FILE* f; f= fopen("dump.bin", "w"); fwrite(buf, buflen, 1, f); fclose(f); exit(-1); } totbytes += buflen; totevents += nevents; devicebytes[j] += buflen; deviceevents[j] += nevents; if(nloops == 1000) { printf(" %u)bps:%" PRIu64 " totbytes:%" PRIu64 " - evts/s:%" PRIu64 " totevs:%" PRIu64 " \n", j, (devicebytes[j] - olddevicebytes[j]), devicebytes[j], (deviceevents[j] - olddeviceevents[j]), deviceevents[j]); olddevicebytes[j] = devicebytes[j]; olddeviceevents[j] = deviceevents[j]; } } // // XXX this should check the buffer sizes and sleep only if they are all below a certain // threshold. // usleep(1000); if(nloops == 1000) { printf("bps:%" PRIu64 " totbytes:%" PRIu64 " - evts/s:%" PRIu64 " totevs:%" PRIu64 "\n", totbytes - oldtotbytes, totbytes, totevents - oldtotevents, totevents); oldtotbytes = totbytes; oldtotevents = totevents; nloops = 0; } nloops++; } scap_close(h); return 0; }
scap_t* scap_open_live_int(char *error, proc_entry_callback proc_callback, void* proc_callback_context, bool import_users) { #if !defined(HAS_CAPTURE) snprintf(error, SCAP_LASTERR_SIZE, "live capture not supported on %s", PLATFORM_NAME); return NULL; #else uint32_t j; char filename[SCAP_MAX_PATH_SIZE]; scap_t* handle = NULL; int len; uint32_t ndevs; uint32_t res; // // Allocate the handle // handle = (scap_t*)malloc(sizeof(scap_t)); if(!handle) { snprintf(error, SCAP_LASTERR_SIZE, "error allocating the scap_t structure"); return NULL; } // // Preliminary initializations // memset(handle, 0, sizeof(scap_t)); // // Find out how many devices we have to open, which equals to the number of CPUs // ndevs = sysconf(_SC_NPROCESSORS_ONLN); // // Allocate the device descriptors. // len = RING_BUF_SIZE * 2; handle->m_devs = (scap_device*)malloc(ndevs * sizeof(scap_device)); if(!handle->m_devs) { scap_close(handle); snprintf(error, SCAP_LASTERR_SIZE, "error allocating the device handles"); return NULL; } for(j = 0; j < ndevs; j++) { handle->m_devs[j].m_buffer = (char*)MAP_FAILED; handle->m_devs[j].m_bufinfo = (struct ppm_ring_buffer_info*)MAP_FAILED; } handle->m_ndevs = ndevs; // // Extract machine information // handle->m_proc_callback = proc_callback; handle->m_proc_callback_context = proc_callback_context; handle->m_machine_info.num_cpus = sysconf(_SC_NPROCESSORS_ONLN); handle->m_machine_info.memory_size_bytes = (uint64_t)sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE); gethostname(handle->m_machine_info.hostname, sizeof(handle->m_machine_info.hostname) / sizeof(handle->m_machine_info.hostname[0])); handle->m_machine_info.reserved1 = 0; handle->m_machine_info.reserved2 = 0; handle->m_machine_info.reserved3 = 0; handle->m_machine_info.reserved4 = 0; handle->m_driver_procinfo = NULL; // // Create the interface list // if(scap_create_iflist(handle) != SCAP_SUCCESS) { scap_close(handle); snprintf(error, SCAP_LASTERR_SIZE, "error creating the interface list"); return NULL; } // // Create the user list // if(import_users) { if(scap_create_userlist(handle) != SCAP_SUCCESS) { scap_close(handle); snprintf(error, SCAP_LASTERR_SIZE, "error creating the interface list"); return NULL; } } else { handle->m_userlist = NULL; } handle->m_fake_kernel_proc.tid = -1; handle->m_fake_kernel_proc.pid = -1; handle->m_fake_kernel_proc.flags = 0; snprintf(handle->m_fake_kernel_proc.comm, SCAP_MAX_PATH_SIZE, "kernel"); snprintf(handle->m_fake_kernel_proc.exe, SCAP_MAX_PATH_SIZE, "kernel"); handle->m_fake_kernel_proc.args[0] = 0; // // Open and initialize all the devices // for(j = 0; j < handle->m_ndevs; j++) { // // Open the device // sprintf(filename, "%s/dev/sysdig%d", scap_get_host_root(), j); if((handle->m_devs[j].m_fd = open(filename, O_RDWR | O_SYNC)) < 0) { if(errno == EBUSY) { uint32_t curr_max_consumers = get_max_consumers(); snprintf(error, SCAP_LASTERR_SIZE, "Too many sysdig instances attached to device %s. Current value for /sys/module/sysdig_probe/parameters/max_consumers is '%"PRIu32"'.", filename, curr_max_consumers); } else { snprintf(error, SCAP_LASTERR_SIZE, "error opening device %s. Make sure you have root credentials and that the sysdig-probe module is loaded.", filename); } scap_close(handle); return NULL; } // // Map the ring buffer // handle->m_devs[j].m_buffer = (char*)mmap(0, len, PROT_READ, MAP_SHARED, handle->m_devs[j].m_fd, 0); if(handle->m_devs[j].m_buffer == MAP_FAILED) { // we cleanup this fd and then we let scap_close() take care of the other ones close(handle->m_devs[j].m_fd); scap_close(handle); snprintf(error, SCAP_LASTERR_SIZE, "error mapping the ring buffer for device %s", filename); return NULL; } // // Map the ppm_ring_buffer_info that contains the buffer pointers // handle->m_devs[j].m_bufinfo = (struct ppm_ring_buffer_info*)mmap(0, sizeof(struct ppm_ring_buffer_info), PROT_READ | PROT_WRITE, MAP_SHARED, handle->m_devs[j].m_fd, 0); if(handle->m_devs[j].m_bufinfo == MAP_FAILED) { // we cleanup this fd and then we let scap_close() take care of the other ones munmap(handle->m_devs[j].m_buffer, len); close(handle->m_devs[j].m_fd); scap_close(handle); snprintf(error, SCAP_LASTERR_SIZE, "error mapping the ring buffer info for device %s", filename); return NULL; } // // Additional initializations // handle->m_devs[j].m_lastreadsize = 0; handle->m_devs[j].m_sn_len = 0; handle->m_n_consecutive_waits = 0; scap_stop_dropping_mode(handle); } // // Create the process list // error[0] = '\0'; snprintf(filename, sizeof(filename), "%s/proc", scap_get_host_root()); if((res = scap_proc_scan_proc_dir(handle, filename, -1, -1, NULL, error, true)) != SCAP_SUCCESS) { scap_close(handle); snprintf(error, SCAP_LASTERR_SIZE, "error creating the process list. Make sure you have root credentials."); return NULL; } // // Now that sysdig has done all its /proc parsing, start the capture // scap_start_capture(handle); return handle; #endif // HAS_CAPTURE }
int main(int argc, char *argv[]) { char error[256]; int capture = 1; time_t last_refresh_t; scap_t *h ; //apro la cattura live degli eventi read_argv(argc, argv); if(global_data.export_elk) init_connection_socket(); if(global_data.show_help_enabled){ print_help(); return(1); } printf("\n\t\t INIZIO INIZIALIZZAZIONE \n"); if( ( h = scap_open_live(error)) == NULL){ printf("Unable to connect to open sysdig: %s\n", error); return(false); } //setto i filtri per gli eventi da catturare solo se la cattura è live scap_clear_eventmask(h); if(scap_set_eventmask(h, PPME_CLONE_16_X) != SCAP_SUCCESS) printf("[ERROR] scap call failed: old driver ?\n"); if(scap_set_eventmask(h, PPME_PROCEXIT_E) != SCAP_SUCCESS) printf("[ERROR] scap call failed: old driver ?\n"); if(scap_set_eventmask(h, PPM_SC_EXIT_GROUP) != SCAP_SUCCESS) printf("[ERROR] scap call failed: old driver ?\n"); if(scap_set_eventmask(h, PPM_SC_EXIT) != SCAP_SUCCESS) printf("[ERROR] scap call failed: old driver ?\n"); if(global_data.get_all_proc) init_add_active_proc(h); printf("\n\t\t FINE INIZIALIZZAZIONE \n"); //ciclo di cattura last_refresh_t = time(NULL); while(capture) { struct ppm_evt_hdr* ev; u_int16_t cpuid; int32_t res = scap_next(h, &ev, &cpuid); if(res > 0 ) { printf("[ERROR] %s\n", scap_getlasterr(h)); scap_close(h); break; } else if( res == SCAP_SUCCESS ) { handle_event(ev,cpuid,h); } else if( res != -1 ) //timeout fprintf(stderr, "scap_next() returned %d\n", res); /*si aggiornano i dati ogni refresh_t secondi (5 default) (XXX numero da regolare) */ if( (time(NULL) - last_refresh_t) > global_data.refresh_t){ manage_data(h); last_refresh_t = time(NULL); } } //chiudo la cattura live degli eventi close(global_data.socket_desc); scap_close(h); }