void sinsp::init() { // // Retrieve machine information // m_machine_info = scap_get_machine_info(m_h); if(m_machine_info != NULL) { m_num_cpus = m_machine_info->num_cpus; } else { ASSERT(false); m_num_cpus = 0; } // // Reset the thread manager // m_thread_manager->clear(); // // Basic inits // #ifdef GATHER_INTERNAL_STATS m_stats.clear(); #endif m_tid_to_remove = -1; m_lastevent_ts = 0; #ifdef HAS_FILTERING m_firstevent_ts = 0; #endif m_fds_to_remove->clear(); m_n_proc_lookups = 0; import_ifaddr_list(); import_thread_table(); import_user_list(); #ifdef HAS_ANALYZER // // Notify the analyzer that we're starting // if(m_analyzer) { m_analyzer->on_capture_start(); } #endif // // If m_snaplen was modified, we set snaplen now // if (m_snaplen != DEFAULT_SNAPLEN) { set_snaplen(m_snaplen); } }
int scan_dump(FILE *fp, off_t size) { struct pcap_file_header hdr; #ifdef __FreeBSD__ struct pcap_sf_pkthdr ph; #else struct pcap_pkthdr ph; #endif off_t pos; /* * Must read the file, compare the header against our new * options (in particular, snaplen) and adjust our options so * that we generate a correct file. Furthermore, check the file * for consistency so that we can append safely. * * XXX this may take a long time for large logs. */ (void) fseek(fp, 0L, SEEK_SET); if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1) { logmsg(LOG_ERR, "Short file header"); return (1); } if (hdr.magic != TCPDUMP_MAGIC || hdr.version_major != PCAP_VERSION_MAJOR || hdr.version_minor != PCAP_VERSION_MINOR || hdr.linktype != hpcap->linktype || hdr.snaplen > PFLOGD_MAXSNAPLEN) { return (1); } pos = sizeof(hdr); while (!feof(fp)) { off_t len = fread((char *)&ph, 1, sizeof(ph), fp); if (len == 0) break; if (len != sizeof(ph)) goto error; if (ph.caplen > hdr.snaplen || ph.caplen > PFLOGD_MAXSNAPLEN) goto error; pos += sizeof(ph) + ph.caplen; if (pos > size) goto error; fseek(fp, ph.caplen, SEEK_CUR); } if (pos != size) goto error; if (hdr.snaplen != cur_snaplen) { logmsg(LOG_WARNING, "Existing file has different snaplen %u, using it", hdr.snaplen); if (set_snaplen(hdr.snaplen)) { logmsg(LOG_WARNING, "Failed, using old settings, offset %llu", (unsigned long long) size); } } return (0); error: logmsg(LOG_ERR, "Corrupted log file."); return (1); }
/* * tries to (re)open log file, nomove flag is used with -x switch * returns 0: success, 1: retry (log moved), -1: error */ int try_reset_dump(int nomove) { struct pcap_file_header hdr; struct stat st; int fd; FILE *fp; if (hpcap == NULL) return (-1); if (dpcap) { flush_buffer(dpcap); fclose(dpcap); dpcap = NULL; } /* * Basically reimplement pcap_dump_open() because it truncates * files and duplicates headers and such. */ fd = priv_open_log(); if (fd < 0) return (-1); fp = fdopen(fd, "a+"); if (fp == NULL) { logmsg(LOG_ERR, "Error: %s: %s", filename, strerror(errno)); close(fd); return (-1); } if (fstat(fileno(fp), &st) == -1) { logmsg(LOG_ERR, "Error: %s: %s", filename, strerror(errno)); fclose(fp); return (-1); } /* set FILE unbuffered, we do our own buffering */ if (setvbuf(fp, NULL, _IONBF, 0)) { logmsg(LOG_ERR, "Failed to set output buffers"); fclose(fp); return (-1); } #define TCPDUMP_MAGIC 0xa1b2c3d4 if (st.st_size == 0) { if (snaplen != cur_snaplen) { logmsg(LOG_NOTICE, "Using snaplen %d", snaplen); if (set_snaplen(snaplen)) logmsg(LOG_WARNING, "Failed, using old settings"); } hdr.magic = TCPDUMP_MAGIC; hdr.version_major = PCAP_VERSION_MAJOR; hdr.version_minor = PCAP_VERSION_MINOR; hdr.thiszone = hpcap->tzoff; hdr.snaplen = hpcap->snapshot; hdr.sigfigs = 0; hdr.linktype = hpcap->linktype; if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1) { fclose(fp); return (-1); } } else if (scan_dump(fp, st.st_size)) { fclose(fp); if (nomove || priv_move_log()) { logmsg(LOG_ERR, "Invalid/incompatible log file, move it away"); return (-1); } return (1); } dpcap = fp; set_suspended(0); flush_buffer(fp); return (0); }
/* based on syslogd privsep */ int priv_init(void) { int i, fd, socks[2], cmd; int snaplen, ret, olderrno; struct passwd *pw; #ifdef __FreeBSD__ for (i = 1; i < NSIG; i++) #else for (i = 1; i < _NSIG; i++) #endif signal(i, SIG_DFL); /* Create sockets */ if (socketpair(AF_LOCAL, SOCK_STREAM, PF_UNSPEC, socks) == -1) err(1, "socketpair() failed"); pw = getpwnam("_pflogd"); if (pw == NULL) errx(1, "unknown user _pflogd"); endpwent(); child_pid = fork(); if (child_pid < 0) err(1, "fork() failed"); if (!child_pid) { gid_t gidset[1]; /* Child - drop privileges and return */ if (chroot(pw->pw_dir) != 0) err(1, "unable to chroot"); if (chdir("/") != 0) err(1, "unable to chdir"); gidset[0] = pw->pw_gid; if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) err(1, "setresgid() failed"); if (setgroups(1, gidset) == -1) err(1, "setgroups() failed"); if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1) err(1, "setresuid() failed"); close(socks[0]); priv_fd = socks[1]; return 0; } /* Father */ /* Pass ALRM/TERM/HUP/INT/QUIT through to child, and accept CHLD */ signal(SIGALRM, sig_pass_to_chld); signal(SIGTERM, sig_pass_to_chld); signal(SIGHUP, sig_pass_to_chld); signal(SIGINT, sig_pass_to_chld); signal(SIGQUIT, sig_pass_to_chld); signal(SIGCHLD, sig_chld); setproctitle("[priv]"); close(socks[1]); while (!gotsig_chld) { if (may_read(socks[0], &cmd, sizeof(int))) break; switch (cmd) { case PRIV_SET_SNAPLEN: logmsg(LOG_DEBUG, "[priv]: msg PRIV_SET_SNAPLENGTH received"); must_read(socks[0], &snaplen, sizeof(int)); ret = set_snaplen(snaplen); if (ret) { logmsg(LOG_NOTICE, "[priv]: set_snaplen failed for snaplen %d", snaplen); } must_write(socks[0], &ret, sizeof(int)); break; case PRIV_OPEN_LOG: logmsg(LOG_DEBUG, "[priv]: msg PRIV_OPEN_LOG received"); /* create or append logs but do not follow symlinks */ fd = open(filename, O_RDWR|O_CREAT|O_APPEND|O_NONBLOCK|O_NOFOLLOW, 0600); olderrno = errno; send_fd(socks[0], fd); if (fd < 0) logmsg(LOG_NOTICE, "[priv]: failed to open %s: %s", filename, strerror(olderrno)); else close(fd); break; case PRIV_MOVE_LOG: logmsg(LOG_DEBUG, "[priv]: msg PRIV_MOVE_LOG received"); ret = move_log(filename); must_write(socks[0], &ret, sizeof(int)); break; default: logmsg(LOG_ERR, "[priv]: unknown command %d", cmd); _exit(1); /* NOTREACHED */ } } _exit(1); }
void sinsp::init() { // // Retrieve machine information // m_machine_info = scap_get_machine_info(m_h); if(m_machine_info != NULL) { m_num_cpus = m_machine_info->num_cpus; } else { ASSERT(false); m_num_cpus = 0; } // // Attach the protocol decoders // add_protodecoders(); // // Allocate the cycle writer // m_cycle_writer = new cycle_writer(); // // Basic inits // #ifdef GATHER_INTERNAL_STATS m_stats.clear(); #endif m_tid_to_remove = -1; m_lastevent_ts = 0; #ifdef HAS_FILTERING m_firstevent_ts = 0; #endif m_fds_to_remove->clear(); m_n_proc_lookups = 0; m_n_proc_lookups_duration_ns = 0; if(m_islive == false) { import_thread_table(); } import_ifaddr_list(); import_user_list(); // // Scan the list to create the proper parent/child dependencies // m_thread_manager->create_child_dependencies(); // // Scan the list to fix the direction of the sockets // m_thread_manager->fix_sockets_coming_from_proc(); #ifdef HAS_ANALYZER // // Notify the analyzer that we're starting // if(m_analyzer) { m_analyzer->on_capture_start(); } #endif // // If m_snaplen was modified, we set snaplen now // if(m_snaplen != DEFAULT_SNAPLEN) { set_snaplen(m_snaplen); } #if defined(HAS_CAPTURE) if(m_islive) { if(scap_getpid_global(m_h, &m_sysdig_pid) != SCAP_SUCCESS) { ASSERT(false); } } #endif }
void sinsp::init() { // // Retrieve machine information // m_machine_info = scap_get_machine_info(m_h); if(m_machine_info != NULL) { m_num_cpus = m_machine_info->num_cpus; } else { ASSERT(false); m_num_cpus = 0; } // // Attach the protocol decoders // #ifndef HAS_ANALYZER add_protodecoders(); #endif // // Allocate the cycle writer // if(m_cycle_writer) { delete m_cycle_writer; m_cycle_writer = NULL; } m_cycle_writer = new cycle_writer(this->is_live()); // // Basic inits // #ifdef GATHER_INTERNAL_STATS m_stats.clear(); #endif m_nevts = 0; m_tid_to_remove = -1; m_lastevent_ts = 0; #ifdef HAS_FILTERING m_firstevent_ts = 0; #endif m_fds_to_remove->clear(); m_n_proc_lookups = 0; m_n_proc_lookups_duration_ns = 0; // // Return the tracers to the pool and clear the tracers list // for(auto it = m_partial_tracers_list.begin(); it != m_partial_tracers_list.end(); ++it) { m_partial_tracers_pool->push(*it); } m_partial_tracers_list.clear(); // // If we're reading from file, we try to pre-parse the container events before // importing the thread table, so that thread table filtering will work with // container filters // if(m_islive == false) { uint64_t off = scap_ftell(m_h); scap_evt* pevent; uint16_t pcpuid; uint32_t ncnt = 0; // // Count how many container events we have // while(true) { int32_t res = scap_next(m_h, &pevent, &pcpuid); if(res == SCAP_SUCCESS) { if((pevent->type != PPME_CONTAINER_E) && (pevent->type != PPME_CONTAINER_JSON_E)) { break; } else { ncnt++; continue; } } else { break; } } // // Rewind and consume the exact number of events // scap_fseek(m_h, off); for(uint32_t j = 0; j < ncnt; j++) { sinsp_evt* tevt; next(&tevt); } } if(m_islive == false || m_filter_proc_table_when_saving == true) { import_thread_table(); } import_ifaddr_list(); import_user_list(); // // Scan the list to create the proper parent/child dependencies // m_thread_manager->create_child_dependencies(); // // Scan the list to fix the direction of the sockets // m_thread_manager->fix_sockets_coming_from_proc(); #ifdef HAS_ANALYZER // // Notify the analyzer that we're starting // if(m_analyzer) { m_analyzer->on_capture_start(); } #endif // // If m_snaplen was modified, we set snaplen now // if(m_snaplen != DEFAULT_SNAPLEN) { set_snaplen(m_snaplen); } #if defined(HAS_CAPTURE) if(m_islive) { if(scap_getpid_global(m_h, &m_sysdig_pid) != SCAP_SUCCESS) { ASSERT(false); } } #endif }