Commit 06802dd3 authored by Olav Kvittem's avatar Olav Kvittem
Browse files

option -o report-file/fifo

parent 44a2cda4
......@@ -22,9 +22,13 @@
* 2015-07-02 Olav Kvittem <oak@uninett.no>
* added reading pcap to disk, using kernel timestamp, forking write process to disk
* bug: reading AF_PACKET does not receive any packets
* 2020-11-26 Olav Kvittem added -z for stdout pipe size
* caveats: only implemented for rec_to_file()
*
*****************************************************************************/
#ifdef __linux__
#define _GNU_SOURCE
#endif
#include <config.h>
#include <rude.h>
#include <mcast.h>
......@@ -32,13 +36,15 @@
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <linux/fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sched.h>
#include <sys/mman.h>
......@@ -105,6 +111,8 @@ static int fork_write();
int main_socket = 0; /* The socket to listen to */
int main_file = 0; /* File to read from/to write to */
int main_output = 0; /* file to write output (is main_file if not fork) */
int print_fd; /* file to send print to */
FILE* print_file; /* file to send print to */
unsigned long pkt_count = 0; /* Counter for received/processed packets */
struct flow_stat *flows = NULL; /* List of flows for runtime statistics */
int nflows = 0;
......@@ -130,6 +138,7 @@ char *obuffer=NULL;
int pipefd[2]; // a pipe for writing to file in a subprocess
int udp_buffer_size=1024*1024; // default value
int pipe_buffer_size = 0;
......@@ -154,13 +163,8 @@ int main(int argc, char **argv)
int use_ip6=0;
int ifindex = -1;
printf("crude version %s, Copyright (C) 1999 Juha Laine and Sampo Saaristo\n"
"crude comes with ABSOLUTELY NO WARRANTY!\n"
"This is free software, and you are welcome to redistribute it\n"
"under GNU GENERAL PUBLIC LICENSE Version 2.\n",VERSION);
while((retval >= 0) &&
((cmd_char = getopt(argc,argv,"Ahvd:p:C:fi:kl:P:n:s:6D:b:")) != EOF))
((cmd_char = getopt(argc,argv,"Ahvd:p:C:fi:kl:P:n:o:s:6D:b:z:")) != EOF))
{
switch(cmd_char)
{
......@@ -324,6 +328,26 @@ int main(int argc, char **argv)
}
break;
case 'o':
if(optarg != NULL)
{
if ( ( print_fd = open(optarg, O_RDWR|O_CREAT|O_TRUNC, 0644) ) < 0)
{
RUDEBUG1("crude: couldn't open file %s: %s\n",optarg,strerror(errno));
retval = -5;
}
else
{
retval += 8;
}
}
else
{
RUDEBUG1("crude: invalid commandline arguments!\n");
retval = -2;
}
break;
case 'P':
if(optarg != NULL)
{
......@@ -427,7 +451,15 @@ int main(int argc, char **argv)
break;
case '6':
use_ip6 = 1;
use_ip6 = 1;
break;
case 'z':
if(optarg != NULL){
pipe_buffer_size = atoi(optarg);
} else {
RUDEBUG1("crude: invalid pipe buffer size argument!\n");
}
break;
case 'D':
......@@ -552,10 +584,12 @@ static void usage(char *name)
"\t-d file = decode the file to stdout\n"
"\t-p port = port to listen to\n"
"\t-b size = UDP receive buffer size(1MB)\n"
"\t-z size = output pipe buffer size(64KB linux)\n"
"\t-i addr = numeric IP addres for the interface to listen to\n"
"\t-6 = use ipv6\n"
"\t-D if_name = interface name(e.g. eth0) to be used-use only with multicast and -i option\n"
"\t-l file = direct undecoded output to file (fastest method!)\n"
"\t-o file = print formatted to file\n"
"\t default is to decode the output to stdout\n"
"\t-P priority = process realtime priority {1-90}\n\n"
"\t-s #[,# ...] = don't record: get runtime stats for specified flows\n"
......@@ -1204,10 +1238,10 @@ static int fork_write( ){
} else { // in child - read and write to disk
close(pipefd[1]); // Child is read only
signal(SIGINT, SIG_IGN); // ignore signal - just wait for eof
int bytes;
int bytes; ssize_t got_bytes;
while( (bytes=read(pipefd[0], filebuffer, ochunksize)) > 0){
write( main_file, filebuffer, bytes);
got_bytes=write( main_file, filebuffer, bytes);
RUDEBUG7("crude: writing to disk %u \n", bytes) ;
}
exit(0);
......@@ -1284,7 +1318,7 @@ static void get_str_addr(struct sockaddr_storage src_addr,char buffer[]){
}
/*
* rec_n_print() - print information of received packets to stdout
* rec_n_print() - print information of received packets in text form
*/
static int rec_n_print(unsigned short port, unsigned long limit)
{
......@@ -1303,6 +1337,8 @@ static int rec_n_print(unsigned short port, unsigned long limit)
struct cmsghdr *cmptr = NULL;
#define CONTROLLEN (sizeof(struct cmsghdr) + sizeof(int))
char buffer[PMAXSIZE], str1[INET6_ADDRSTRLEN], str2[INET6_ADDRSTRLEN];
char out_line[200];
struct stat st;
/* Initialize some variables */
memset(buffer,0,PMAXSIZE);
......@@ -1332,6 +1368,33 @@ static int rec_n_print(unsigned short port, unsigned long limit)
{
RUDEBUG1("crude: unable to receive HOPLIMIT values for IPv6: %s\n",strerror(errno));
}
if ( print_fd ){
if( pipe_buffer_size > 0){
if ( ! fstat( print_fd, &st) && S_ISFIFO(st.st_mode) ){ // set output buffer size
int p_size = fcntl( print_fd, F_SETPIPE_SZ, pipe_buffer_size );
if ( p_size > 0 ){
fprintf( stderr, "output pipe size : %d\n", p_size );
} else {
RUDEBUG1("crude: unable to set ouput pipe size %d : %s\n", pipe_buffer_size, strerror(errno));
return(-9);
}
} else {
RUDEBUG1("Option -z specified, but output is not to a pipe\n");
return(-9);
}
}
print_file = fdopen( print_fd, "w+" );
} else {
print_file = stdout;
}
fprintf( print_file, "crude version %s, Copyright (C) 1999 Juha Laine and Sampo Saaristo\n"
"crude comes with ABSOLUTELY NO WARRANTY!\n"
"This is free software, and you are welcome to redistribute it\n"
"under GNU GENERAL PUBLIC LICENSE Version 2.\n",VERSION);
for( ; ; )
{
rec_bytes = recvmsg(main_socket, &msgh, MSG_WAITALL);
......@@ -1382,7 +1445,7 @@ static int rec_n_print(unsigned short port, unsigned long limit)
get_str_addr(src_addr,str1);
get_str_addr(d_add,str2);
printf("ID=%lu SEQ=%lu SRC=%s:%hu DST=%s:%hu "
fprintf( print_file, "ID=%lu SEQ=%lu SRC=%s:%hu DST=%s:%hu "
"Tx=%lu.%06lu Rx=%ld.%06ld SIZE=%ld HOPLIMIT=%d\n",
(unsigned long)ntohl(udp_ptr->flow_id),
(unsigned long)ntohl(udp_ptr->sequence_number),
......@@ -1390,7 +1453,7 @@ static int rec_n_print(unsigned short port, unsigned long limit)
(unsigned long)ntohl(udp_ptr->tx_time_seconds),
(unsigned long)ntohl(udp_ptr->tx_time_useconds),
time1.tv_sec, time1.tv_usec, rec_bytes, received_ttl );
fflush(stdout);
fflush(print_file);
}
if((limit != 0) && (pkt_count >= limit)){ break; }
......
......@@ -35,7 +35,7 @@
#define PMAXSIZE 32768 /* Maximum accepted UDP-data field/packet size */
#define MINDURAT 0.001 /* Minimum allowed flow duration in seconds (float) */
#define VERSION "0.9.7"
#define VERSION "0.9.8"
/*
* Enumeration definition for different (known) flow types
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment