static stream_t open_dst(stream_addr_t* addr, const caphead_t cp, const char* comment){ /* default to stdout */ if( !stream_addr_is_set(addr) ){ if ( isatty(STDOUT_FILENO) ){ fprintf(stderr, "%s: Cannot output to a terminal, either specify a file using `-o FILENAME' or\n" " redirect output.\n", program_name); return NULL; } /* stdout is not a terminal so user probably want to use redirection */ stream_addr_str(addr, "/dev/stdout", 0); } if ( !quiet ){ fprintf(stderr, "%s: Opening file stream: %s\n", program_name, stream_addr_ntoa(addr)); } int ret; stream_t st = NULL; if ( (ret=stream_create(&st, addr, cp->nic, cp->mampid, comment)) != 0 ){ fprintf(stderr, "%s: stream_create failed with code %d: %s.\n", program_name, ret, caputils_error_string(ret)); return NULL; } return st; }
void send_packet(struct destination* dst){ const size_t payload_size = dst->buffer.end - dst->buffer.begin; const uint32_t seqnr = ntohl(dst->shead->sequencenr); assert(payload_size > 0); dst->shead->flags = htonl(dst->shead->flags); dst->shead->nopkts = htonl(dst->sendcount); /* see destination.h for buffer layout */ const u_char* data = dst->buffer.begin; size_t frame_size = payload_size; /* send header is prepended to data and must be included in size */ if ( dst->want_sendhead ){ data -= sizeof(struct sendhead); frame_size += sizeof(struct sendhead); } assert(frame_size <= MPinfo->MTU && "send_packet(..) payload size is greater than MTU"); /* ethernet streams requires ethernet header to be prepended */ if ( dst->want_ethhead ){ data -= sizeof(struct ethhdr); frame_size += sizeof(struct ethhdr); } int ret = stream_write(dst->stream, data, frame_size); logmsg(verbose, SENDER, "Filter %d sending %zd bytes with %d packets\n", dst->filter->filter_id, frame_size, ntohl(dst->shead->nopkts)); if ( debug_flag ){ if ( ret == 0 ){ logmsg(verbose, SENDER, "\tcaputils-%s\n", caputils_version(NULL)); logmsg(verbose, SENDER, "\tdst: %s\n", stream_addr_ntoa(&dst->filter->dest)); logmsg(verbose, SENDER, "\tPacket (%zd bytes incl all headers):\n", frame_size); if ( dst->want_ethhead ){ logmsg(verbose, SENDER, "\t\tEthernet (+%zd bytes)\n", sizeof(struct ethhdr)); } if ( dst->want_sendhead ){ logmsg(verbose, SENDER, "\t\tSendheader [Seqnr=%04lx, nopkts=%04d] (+%zd bytes)\n", (unsigned long int)seqnr, ntohl(dst->shead->nopkts), sizeof(struct sendhead)); } logmsg(verbose, SENDER, "\t\tPayload (+%zd bytes)\n", payload_size); logmsg(verbose, SENDER, "\tsizeof(caphead): %zd bytes\n", sizeof(struct cap_header)); logmsg(verbose, SENDER, "\tMTU: %zd bytes\n", MPinfo->MTU); } else { logmsg(stderr, SENDER, "\tstream_write() returned %d: %s\n", ret, strerror(ret)); logmsg(verbose, SENDER, "\tPacket length = %zd bytes, Eth %zd, Send %zd, Cap %zd bytes\n", frame_size, sizeof(struct ethhdr), sizeof(struct sendhead), sizeof(struct cap_header)); } } //Update the sequence number and reset dst->shead->sequencenr = htonl((seqnr+1) % 0xFFFF); dst->shead->flags = 0; dst->sendcount = 0; /* update stats */ MPstats->written_count += dst->sendcount; MPstats->sent_count++; /* restore packet buffer */ dst->buffer.end = dst->buffer.begin; }