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; }
int main(int argc, char **argv){ int ret; /* validate arguments */ if ( argc != 2 ){ fprintf(stderr, "usage: %s FILENAME\n", argv[0]); return 1; } /* load tracefile address */ const char* filename = argv[1]; stream_addr_t addr = STREAM_ADDR_INITIALIZER; stream_addr_str(&addr, filename, 0); /* open stream */ stream_t stream; if ( (ret=stream_open(&stream, &addr, NULL, 0)) != 0 ){ fprintf(stderr, "%s: %s\n", filename, caputils_error_string(ret)); return ret; } /* read packets */ while ( stream_read_cb(stream, handle_packet, NULL, NULL) == 0 ); /* close stream */ stream_close(stream); return 0; }
static void flush_senders(){ /* get current timestamp */ struct timespec now; clock_gettime(CLOCK_REALTIME, &now); for ( int i = 0; i < MAX_FILTERS; i++ ){ struct destination* dst = &MAsd[i]; const size_t payload_size = dst->buffer.end - dst->buffer.begin; if ( payload_size > 0 ){ const int need_flush = dst->state != BUSY && payload_size > 0; /* calculate time since last send. If it was long ago (longer than * MAX_PACKET_AGE) the send buffer is flushed even if it doesn't contain * enough payload for a full packet. */ signed long int sec = (now.tv_sec - dst->last_sent.tv_sec) * 1000; signed long int msec = (now.tv_nsec - dst->last_sent.tv_nsec); msec /= 1000000; /* please keep this division a separate statement. It ensures * that the subtraction above is stored as a signed value. If * the division is put together the subtraction will be * calculated as unsigned (tv_psec is stored as unsigned), * then divided and only then converted to signed int. */ const signed long int age = sec + msec; const int old_age = age >= MAX_PACKET_AGE; if ( need_flush || old_age ){ send_packet(dst); dst->last_sent = now; } } /* stop destinations flagged for termination */ if ( dst->state == STOP ){ int ret; logmsg(verbose, SENDER, "Closing stream %d\n", dst->index); if ( (ret=stream_close(dst->stream)) != 0 ){ logmsg(stderr, SENDER, "stream_close() returned 0x%08x: %s\n", ret, caputils_error_string(ret)); } dst->stream = NULL; dst->state = IDLE; } } }
static int check(const char* cmdline, int expect_fail){ int ret; /* try to execute */ ret = system(cmdline); if ( ret != 0 && !expect_fail ){ fprintf(stderr, "capdump_argv: command exited with code %d: \"%s\"\n", WEXITSTATUS(ret), cmdline); return 0; } else if ( ret == 0 && expect_fail ){ fprintf(stderr, "capdump_argv: command exited with code 0 but expected to fail: \"%s\"\n", cmdline); return 0; } else if ( ret != 0 && expect_fail ){ return 1; } stream_t st; stream_addr_t addr; stream_addr_str(&addr, "test-temp.cap", 0); /* validate output */ if ( (ret=stream_open(&st, &addr, NULL, 0)) != 0 ){ fprintf(stderr, "capdump_argv: command did not create a valid trace: \"%s\"\n", cmdline); fprintf(stderr, "capdump_argv: stream_open(..) returned %d: %s\n", ret, caputils_error_string(ret)); return 0; } caphead_t cp; while ( stream_read(st, &cp, NULL, NULL) == 0 ); /* do nothing */ const stream_stat_t* stat = stream_get_stat(st); if ( stat->read != 1 ){ fprintf(stderr, "capdump_argv: command created and incorrect trace: \"%s\"\n", cmdline); fprintf(stderr, "capdump_argv: expected 1 packet, got %"PRIu64".\n", stat->read); stream_close(st); unlink("test-temp.cap"); return 0; } stream_close(st); unlink("test-temp.cap"); return 1; }
int main (int argc, char **argv){ /* extract program name from path. e.g. /path/to/MArCd -> MArCd */ const char* separator = strrchr(argv[0], '/'); if ( separator ){ program_name = separator + 1; } else { program_name = argv[0]; } /* setup capture header */ struct cap_header cp; strncpy(cp.nic, "CONV", CAPHEAD_NICLEN); gethostname(cp.mampid, 8); /* defaults */ char* comments = strdup("converted from pcap with pcap2cap-" CAPUTILS_VERSION); stream_addr_t dst = STREAM_ADDR_INITIALIZER; int op; int option_index; while ( (op = getopt_long (argc, argv, shortopts, longopts, &option_index)) != -1 ){ switch (op){ case 'c': comments = strdup(optarg); break; case 'm': strncpy(cp.mampid, optarg, 8); break; case 'i': /* --iface */ strncpy(cp.nic, optarg, CAPHEAD_NICLEN); cp.nic[CAPHEAD_NICLEN-1] = 0; /* force null-terminator */ break; case 'l': caplen = atoi(optarg); break; case 'o': stream_addr_str(&dst, optarg, 0); break; case 'q': /* --quiet */ quiet = 1; break; case 'h': show_usage(); return 0; break; default: printf ("?? getopt returned character code 0%o ??\n", op); } } /* open input/output */ pcap_t* pcap = open_src(argc, argv, &cp); stream_t st = open_dst(&dst, &cp, comments); if ( !(pcap && st) ){ return 1; /* error already shown */ } /* comment is no longer needed */ free(comments); comments = NULL; /* setup signal handler so it can handle ctrl-c etc with proper closing of streams */ signal(SIGINT, sighandler); const u_char* packet; struct pcap_pkthdr pcapHeader; unsigned long long pktCount = 0; while ( (packet=pcap_next(pcap, &pcapHeader)) && run ){ cp.ts.tv_sec = pcapHeader.ts.tv_sec; /* Copy and convert the timestamp provided by PCAP, assumes _usec. If nsec will be present adjust! */ cp.ts.tv_psec = pcapHeader.ts.tv_usec * 1e6; cp.len = pcapHeader.len; /* The Wire-lenght of the frame */ cp.caplen = min(pcapHeader.caplen, caplen); // Let the user know that we are alive, good when processing large files. if ( !quiet && pktCount++ % 1000 == 0 ) { fprintf(stderr, "."); fflush(stderr); } // Save a copy of the frame to the new file. int ret; if ( (ret=stream_write_separate(st, &cp, packet, cp.caplen)) != 0 ) { fprintf(stderr, "stream_write(..) returned %d: %s\n", ret, caputils_error_string(ret)); } } /* Release resources */ stream_close(st); stream_addr_reset(&dst); pcap_close(pcap); if ( !quiet ){ fprintf(stderr, "\n%s: There was a total of %lld packets converted.\n", program_name, pktCount); } return 0; }
int main(int argc, char **argv){ /* extract program name from path. e.g. /path/to/MArCd -> MArCd */ const char* separator = strrchr(argv[0], '/'); if ( separator ){ program_name = separator + 1; } else { program_name = argv[0]; } struct filter filter; if ( filter_from_argv(&argc, argv, &filter) != 0 ){ return 0; /* error already shown */ } int op, option_index = -1; while ( (op = getopt_long(argc, argv, shortopts, longopts, &option_index)) != -1 ){ switch (op){ case 0: /* long opt */ case '?': /* unknown opt */ break; case '1': case '2': case '3': case '4': { const unsigned int mask = (7<<FORMAT_LAYER_BIT); flags &= ~mask; /* reset all layer bits */ flags |= (op-'0')<<FORMAT_LAYER_BIT; break; } case 'd': /* --calender */ flags |= FORMAT_DATE_STR | FORMAT_DATE_UTC; break; case 'D': /* --localtime */ flags |= FORMAT_DATE_STR | FORMAT_DATE_LOCALTIME; break; case 'a': /* --absolute */ flags &= ~FORMAT_REL_TIMESTAMP; break; case 'r': /* --relative */ flags |= FORMAT_REL_TIMESTAMP; break; case 'H': /* --headers */ flags |= FORMAT_HEADER; break; case 'p': /* --packets */ max_packets = atoi(optarg); break; case 'c': /* --packets */ max_matched_packets = atoi(optarg); break; case 't': /* --timeout */ { int tmp = atoi(optarg); timeout.tv_sec = tmp / 1000; timeout.tv_usec = tmp % 1000 * 1000; } break; case 'x': /* --hexdump */ flags |= FORMAT_HEXDUMP; break; case 'i': /* --iface */ iface = optarg; break; case ARGUMENT_VERSION: /* --version */ show_version(); return 0; case 'h': /* --help */ show_usage(); return 0; default: fprintf (stderr, "%s: argument '-%c' declared but not handled\n", argv[0], op); } } int ret; /* Open stream(s) */ struct stream* stream; if ( (ret=stream_from_getopt(&stream, argv, optind, argc, iface, "-", program_name, 0)) != 0 ) { return ret; /* Error already shown */ } const stream_stat_t* stat = stream_get_stat(stream); stream_print_info(stream, stderr); /* handle C-c */ signal(SIGINT, handle_sigint); /* setup formatter */ struct format format; format_setup(&format, flags); uint64_t matched = 0; while ( keep_running ) { /* A short timeout is used to allow the application to "breathe", i.e * terminate if SIGINT was received. */ struct timeval tv = timeout; /* Read the next packet */ cap_head* cp; ret = stream_read(stream, &cp, NULL, &tv); if ( ret == EAGAIN ){ continue; /* timeout */ } else if ( ret != 0 ){ break; /* shutdown or error */ } /* identify connection even if filter doesn't match so id will be * deterministic when changing the filter */ connection_id(cp); if ( filter_match(&filter, cp->payload, cp) ){ format_pkg(stdout, &format, cp); matched++; } else { format_ignore(stdout, &format, cp); } if ( max_packets > 0 && stat->matched >= max_packets) { /* Read enough pkts lets break. */ break; } if ( max_matched_packets > 0 && matched >= max_matched_packets) { /* Read enough pkts lets break. */ break; } } /* if ret == -1 the stream was closed properly (e.g EOF or TCP shutdown) * In addition EINTR should not give any errors because it is implied when the * user presses C-c */ if ( ret > 0 && ret != EINTR ){ fprintf(stderr, "stream_read() returned 0x%08X: %s\n", ret, caputils_error_string(ret)); } /* Write stats */ fprintf(stderr, "%"PRIu64" packets read.\n", stat->read); fprintf(stderr, "%"PRIu64" packets matched filter.\n", matched); /* Release resources */ stream_close(stream); filter_close(&filter); return 0; }