void* sender_caputils(struct thread_data* td, void *ptr){ send_proc_t* proc = (send_proc_t*)ptr; /* Extract the parameters that we got from our master, i.e. parent process.. */ const int nics = proc->nics; /* The number of active CIs */ logmsg(stderr, SENDER, "Initializing. There are %d captures.\n", nics); /* initialize timestamp */ { struct timespec tmp; clock_gettime(CLOCK_REALTIME, &tmp); for ( int i = 0; i < MAX_FILTERS; i++ ){ MAsd[i].last_sent = tmp; } } /* unlock main thread */ thread_init_finished(td, 0); /* sender loop */ while( terminateThreads == 0 ){ flush_senders(); fill_senders(proc); } logmsg(verbose, SENDER, "Flushing sendbuffers.\n"); flushAll(1); logmsg(stderr, SENDER, "Finished.\n"); return(NULL) ; }
void* sender_capfile(struct thread_data* td, void* ptr){ send_proc_t* proc = (send_proc_t*)ptr; logmsg(stderr, SENDER, "Initializing (local mode).\n"); struct destination dst; destination_init(&dst, 0); dst.want_ethhead = 0; dst.want_sendhead = 0; //if ( (ret=createstream(&con.stream, &dest, NULL, mampid_get(MPinfo->id), MPinfo->comment)) != 0 ){ // logmsg(stderr, SENDER, " createstream() returned 0x%08lx: %s\n", ret, caputils_error_string(ret)); // sem_post(proc->semaphore); /* unlock main thread */ // return NULL; //} /* unlock main thread */ thread_init_finished(td, 0); while( terminateThreads == 0 ){ int oldest = oldest_packet(proc->nics, proc->semaphore); /* couldn't find a packet, gave up waiting. we are probably terminating. */ if ( oldest == -1 ){ continue; } struct CI* CI = &_CI[oldest]; struct write_header* whead = CI_packet(CI, CI->readpos); copy_to_sendbuffer(&dst, whead, CI); send_packet(&dst); } destination_free(&dst); logmsg(stderr, SENDER, "Finished (local).\n"); return NULL; }
void* control(struct thread_data* td, void* prt){ int ret; /* redirect output */ marc_set_output_handler(output_wrapper_n, output_wrapper_v, stderr, verbose); /* get version of libcap_utils */ caputils_version_t cv; caputils_version(&cv); /* setup libmarc */ struct marc_client_info info = {0,}; info.client_ip = NULL; info.server_ip = marc_ip; info.client_port = port; info.max_filters = MAX_FILTERS; info.noCI = noCI; info.ma_mtu = MPinfo->MTU; info.version.caputils.major = cv.major; info.version.caputils.minor = cv.minor; info.version.caputils.micro = cv.micro; info.version.self.major = VERSION_MAJOR; info.version.self.minor = VERSION_MINOR; info.version.self.micro = VERSION_MICRO; info.drivers = 0; #ifdef HAVE_DRIVER_RAW info.drivers |= 1; #endif #ifdef HAVE_DRIVER_PCAP info.drivers |= 2; #endif #if defined(HAVE_DRIVER_DAG) || defined(HAVE_DRIVER_DAG_LEGACY) info.drivers |= 4; #endif for ( int i = 0; i < noCI; i++ ){ strncpy(info.CI[i].iface, _CI[i].iface, 8); } if ( (ret=marc_init_client(&client, MPinfo->iface, &info)) != 0 ){ fprintf(stderr, "marc_init_client() returned %d: %s\n", ret, strerror(ret)); thread_init_finished(td, ret); return NULL; } logmsg(verbose, CONTROL, "Listening on %s:%d.\n", info.client_ip, info.client_port); /* setup status ALRM handler */ { /* unblock SIGALRM in case it was blocked (LinuxThreads seems to inhibit this behaviour) */ sigset_t sigmask; sigemptyset(&sigmask); sigaddset(&sigmask, SIGALRM); pthread_sigmask(SIG_UNBLOCK, &sigmask, NULL); /* timer */ struct itimerval difftime; difftime.it_interval.tv_sec = STATUS_INTERVAL; difftime.it_interval.tv_usec = 0; difftime.it_value.tv_sec = STATUS_INTERVAL; difftime.it_value.tv_usec = 0; signal(SIGALRM, CIstatus); setitimer(ITIMER_REAL, &difftime, NULL); } /* Catch various signals to send a distress signal to MArCd */ signal(SIGSEGV, distress); signal(SIGBUS, distress); signal(SIGILL, distress); thread_init_finished(td, 0); /* process messages from MArCd */ MPMessage event; size_t size; int auth_retry = 0; while( terminateThreads==0 ){ struct timeval timeout = {1, 0}; /* 1 sec timeout */ if ( !is_authorized() && auth_retry >= 15 ){ logmsg(stderr, CONTROL, "No reply from MArCd (make sure MArCd is running). Resending request.\n"); marc_client_init_request(client, &info); auth_retry = 0; } /* get next message */ switch ( (ret=marc_poll_event(client, &event, &size, NULL, NULL, &timeout)) ){ case EAGAIN: /* delivered if using a timeout */ case EINTR: /* interuped */ if ( auth_retry >= 0 ){ auth_retry++; } continue; case 0: /* success, continue processing */ /* always handle authorization event */ if ( event.type == MP_CONTROL_AUTHORIZE_EVENT || event.type == MP_CONTROL_AUTHORIZE_REQUEST ){ break; } /* only handle other events if authorized */ if ( !is_authorized() ){ logmsg(verbose, CONTROL, "MP not authorized, ignoring message of type %d\n", event.type); continue; } break; default: /* error has been raised */ fprintf(stderr, "marc_poll_event() returned %d: %s\n", ret, strerror(ret)); return NULL; } if ( debug_flag ){ logmsg(verbose, CONTROL, "Got message %d (%zd bytes) from MArCd.\n", event.type, size); } /* act */ switch (event.type) { /* ntohl not needed, called by marc_poll_event */ case MP_CONTROL_AUTHORIZE_EVENT: mp_auth(&event.auth); auth_retry = -1; break; case MP_CONTROL_AUTHORIZE_REQUEST: logmsg(verbose, CONTROL, "Got an authorization request, asking MArCd for a new authorization message.\n"); marc_client_init_request(client, &info); break; case MP_FILTER_EVENT: mp_filter(&event.filter, size); break; case MP_FILTER_RELOAD_EVENT: mp_filter_reload(ntohl(event.filter_id.id)); break; case MP_FILTER_DEL_EVENT: mp_filter_del(ntohl(event.filter_id.id)); break; case MP_FILTER_REQUEST_EVENT: mp_filter_reload(ntohl(event.filter_id.id)); break; case MP_FILTER_INVALID_ID: logmsg(verbose, CONTROL, "Filter request failed: invalid id\n"); break; case MP_CONTROL_TERMINATE_EVENT: logmsg(stderr, CONTROL, "Got termination request\n"); terminateThreads = 1; break; default: logmsg(verbose, CONTROL, "Got unhandled event of type %d containing %zd bytes (including header).\n", event.type, size); logmsg(verbose, CONTROL, "PAYLOAD (%zd bytes):\n", size-4-sizeof(mampid_t)); hexdump(verbose, event.payload, size-4-sizeof(mampid_t)); break; } } /* inform MArCd that MP is terminating (properly) */ { MPMessage ev; ev.type = MP_CONTROL_TERMINATE_EVENT; mampid_set(ev.MAMPid, MPinfo->id); if ( (ret=marc_push_event(client, &ev, NULL)) != 0 ){ logmsg(stderr, CONTROL, "marc_push_event() returned %d: %s\n", ret, strerror(ret)); } } marc_cleanup(client); client = NULL; return NULL; }