Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Simple tool to discard broken packets and re-synchronize a pcap dump.
- * (c) 2015 Konrad Rieck (konrad@mlsec.org)
- * --
- * Compilation: gcc -Wall -o pcapsync pcapsync.c
- */
- #include <stdint.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- /* Maximum delay between two packets (24h) */
- int max_pkt_delay = 60 * 60 * 24;
- /* Maximum packet size (0xffff) */
- int max_pkt_size = 0xffff;
- /* Name of input pcap dump */
- char *pcap_in;
- /* Name of output pcap dump */
- char *pcap_out;
- /* File header adapted from pcap.h */
- struct pcap_file_header {
- uint32_t magic;
- uint16_t version_major;
- uint16_t version_minor;
- int32_t thiszone; /* gmt to local correction */
- uint32_t sigfigs; /* accuracy of timestamps */
- uint32_t snaplen; /* max length saved portion of each pkt */
- uint32_t linktype; /* data link type (LINKTYPE_*) */
- };
- /* Packet header adapted from pcap.h */
- struct pcap_pkt_hdr {
- uint32_t ts_sec; /* time stamp */
- uint32_t ts_usec;
- uint32_t caplen; /* length of portion present */
- uint32_t len; /* length of this packet (off wire) */
- };
- /* Print usage of the tool */
- void print_usage()
- {
- printf("Usage: pcapsync [-d delay] [-s size] pcap-in pcap-out\n"
- " -d delay Maximum packet delay in seconds (Default: %d)\n"
- " -s size Maximum packet size in bytes (Default: %d)\n",
- max_pkt_delay, max_pkt_size);
- }
- /* Parse options using getopt(2) */
- void parse_args(int argc, char **argv)
- {
- int ch;
- while ((ch = getopt(argc, argv, "d:s:")) != -1) {
- switch (ch) {
- case 'd':
- max_pkt_delay = atoi(optarg);
- break;
- case 's':
- max_pkt_size = atoi(optarg);
- break;
- case 'h':
- default:
- print_usage();
- exit(EXIT_FAILURE);
- }
- }
- argc -= optind;
- argv += optind;
- /* Get file names */
- if (argc != 2) {
- print_usage();
- exit(EXIT_FAILURE);
- } else {
- pcap_in = argv[0];
- pcap_out = argv[1];
- }
- }
- /* Sanity check on file header */
- int check_header(struct pcap_file_header *hdr)
- {
- if (hdr->magic == 0xd4c3b2a1) {
- fprintf(stderr, "%s: Wrong endianess\n", pcap_in);
- return 0;
- }
- if (hdr->magic != 0xa1b2c3d4) {
- fprintf(stderr, "%s: Invalid file header\n", pcap_in);
- return 0;
- }
- return 1;
- }
- /* Sanity checks on packet header */
- int check_packet(struct pcap_pkt_hdr *pkt)
- {
- static uint32_t last = 0;
- /* Get time of first packet */
- if (last == 0)
- last = pkt->ts_sec;
- /* Sanity check on header */
- if (pkt->caplen > max_pkt_size)
- return 0;
- if (pkt->caplen > pkt->len)
- return 0;
- if (abs(last - pkt->ts_sec) > max_pkt_delay)
- return 0;
- /* Store timestamp */
- last = pkt->ts_sec;
- return 1;
- }
- /* Main function */
- int main(int argc, char **argv)
- {
- FILE *in = NULL, *out = NULL;
- int ret;
- char *data, buf[256];
- struct pcap_pkt_hdr *pkt = (struct pcap_pkt_hdr *) buf;
- struct pcap_file_header *hdr = (struct pcap_file_header *) buf;
- /* Parse arguments */
- parse_args(argc, argv);
- /* Allocate memory */
- data = malloc(max_pkt_size);
- if (!data) {
- fprintf(stderr, "Could not allocate memory");
- return EXIT_FAILURE;
- }
- /* Open input and output file */
- in = fopen(pcap_in, "r");
- out = fopen(pcap_out, "w");
- if (!in || !out) {
- perror(in ? pcap_out : pcap_in);
- return EXIT_FAILURE;
- }
- /* Read file header */
- ret = fread(hdr, sizeof(struct pcap_file_header), 1, in);
- if (ret != 1) {
- perror(pcap_in);
- return EXIT_FAILURE;
- }
- if (!check_header(hdr))
- return EXIT_FAILURE;
- /* Write file header */
- ret = fwrite(hdr, sizeof(struct pcap_file_header), 1, out);
- if (ret != 1) {
- perror(pcap_out);
- return EXIT_FAILURE;
- }
- while (!feof(in)) {
- /* Attempt to read packet */
- ret = fread(pkt, sizeof(struct pcap_pkt_hdr), 1, in);
- if (ret != 1)
- continue;
- /* Check packet for sanity and move on on error */
- if (!check_packet(pkt)) {
- fseek(in, 1 - sizeof(struct pcap_pkt_hdr), SEEK_CUR);
- continue;
- }
- /* Read packet payload */
- ret = fread(data, pkt->caplen, 1, in);
- if (ret != 1) {
- perror(pcap_in);
- continue;
- }
- /* Write out packet */
- ret = fwrite(buf, sizeof(struct pcap_pkt_hdr), 1, out);
- ret += fwrite(data, pkt->caplen, 1, out);
- if (ret != 2)
- perror(pcap_out);
- }
- /* Cean up */
- free(data);
- fclose(out);
- fclose(in);
- exit(EXIT_SUCCESS);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement