static void fill_senders(const send_proc_t* proc){ static const size_t header_size = sizeof(struct cap_header) + sizeof(struct sendhead); const int oldest = oldest_packet(proc->nics, proc->semaphore); /* couldn't find a packet, gave up waiting. we are probably terminating. */ if ( oldest == -1 ){ return; } /* timeout, flush all buffers */ if( oldest == -2 ){ flushAll(0); return; } struct CI* CI = &_CI[oldest]; struct write_header* whead = CI_packet(CI, CI->readpos); struct cap_header* head = whead->cp; struct destination* dst = &MAsd[whead->destination]; /* calculate size of sendbuffer and compare with MTU */ const size_t payload_size = dst->buffer.end - dst->buffer.begin; const int larger_mtu = payload_size + head->caplen + header_size > MPinfo->MTU; /* if the current packet doesn't fit flush first */ if ( larger_mtu ){ assert(payload_size > 0 && dst->sendcount > 0 && "packet didn't fit into frame but frame is empty"); send_packet(dst); } /* copy packet into buffer */ copy_to_sendbuffer(dst, whead, CI); }
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; }
static int oldest_packet(int nics, sem_t* semaphore){ int oldest = -1; while( oldest == -1 ){ // Loop while we havent gotten any pkts. if ( terminateThreads>0 ) { return -1; } struct picotime timeOldest; // timestamp of oldest packet timeOldest.tv_sec = UINT32_MAX; timeOldest.tv_psec = UINT64_MAX; for( int i = 0; i < nics; i++){ const int readpos = _CI[i].readpos; const struct write_header* whead = CI_packet(&_CI[i], readpos); const struct cap_header* head = whead->cp; /* This destination has no packages yet */ if( whead->used == 0 ) { continue; } if( timecmp(&head->ts, &timeOldest) < 0 ){ timeOldest.tv_sec = head->ts.tv_sec; timeOldest.tv_psec = head->ts.tv_psec; oldest = i; } } /* No packages, wait until some arrives */ if ( oldest==-1 ){ int ret = wait_for_capture(semaphore); if ( ret == ETIMEDOUT ){ return -2; } } } return oldest; }
int capture_loop(struct CI* CI, struct capture_context* cap){ int ret; /* initialize driver */ if ( cap->init && (ret=cap->init(cap)) != 0 ){ sem_post(CI->flag); /* unlock parent */ return ret; /* return error */ } /* flag that thread is ready for capture */ sem_post(CI->flag); /* wait until the MP is authorized until it starts capture */ wait_for_auth(); CI->writepos = 0; /* Reset write-position in memory */ while(terminateThreads==0){ /* calculate pointers into writebuffer */ struct write_header* whead = CI_packet(CI, CI->writepos); struct cap_header* head = whead->cp; unsigned char* packet_buffer = (unsigned char*)head->payload; /* fill details into capture header */ fill_caphead(head, CI->iface, MPinfo->id); /* read a packet */ ssize_t bytes = cap->read_packet(cap, packet_buffer, head); if ( bytes < 0 ){ /* failed to read */ break; } else if ( bytes == 0 ){ /* no data */ continue; } /* stats */ CI->packet_count++; /* return -1 when no filter matches */ if ( push_packet(CI, whead, head, packet_buffer) == -1 ){ continue; } /* stats */ CI->matched_count++; } /* stop capture */ logmsg(verbose, CAPTURE, "CI[%d] stopping capture on %s.\n", CI->id, CI->iface); /* show stats */ if ( cap->stats ){ cap->stats(cap); } /* driver cleanup */ if ( cap->destroy && (ret=cap->destroy(cap)) != 0 ){ return ret; /* return error */ } return 0; }