예제 #1
0
파일: main.c 프로젝트: IgorNstu/SNIFFER
int main(int argc,char *argv[]){
    int r;
    if (argc ==1){
        printf("-e для eth0, -w для wlan0\n");
        return 0;
    }
    while((r=getopt(argc,argv,"we"))!=-1)
        {
            switch(r)
            {
            case 'w':
                printf("Работа с интерфейсом wlan0\n");
                sniff(1);
                break;
            case 'e':
                printf("Работа с интерфейсом eth0\n");
                sniff(2);
                break;
            case '?': printf("-e для eth0, -w для wlan0\n");
                return 0;
            }
        }

    return(0);


}
예제 #2
0
int main(int argc, char** argv) {
    SkCommandLineFlags::SetUsage(
            "Usage: get_images_from_skps -s <dir of skps> -o <dir for output images> --testDecode "
            "-j <output JSON path>\n");

    SkCommandLineFlags::Parse(argc, argv);
    const char* inputs = FLAGS_skps[0];
    gOutputDir = FLAGS_out[0];

    if (!sk_isdir(inputs) || !sk_isdir(gOutputDir)) {
        SkCommandLineFlags::PrintUsage();
        return 1;
    }

    SkOSFile::Iter iter(inputs, "skp");
    for (SkString file; iter.next(&file); ) {
        SkAutoTDelete<SkStream> stream =
                SkStream::NewFromFile(SkOSPath::Join(inputs, file.c_str()).c_str());
        sk_sp<SkPicture> picture(SkPicture::MakeFromStream(stream));

        SkDynamicMemoryWStream scratch;
        Sniffer sniff(file.c_str());
        picture->serialize(&scratch, &sniff);
    }
    int totalUnknowns = 0;
    /**
     JSON results are written out in the following format:
     {
       "failures": {
         "skp1": 12,
         "skp4": 2,
         ...
       },
       "totalFailures": 32,
       "totalSuccesses": 21,
     }
     */
    Json::Value fRoot;
    for(auto it = gSkpToUnknownCount.cbegin(); it != gSkpToUnknownCount.cend(); ++it)
    {
        SkDebugf("%s %d\n", it->first.c_str(), it->second);
        totalUnknowns += it->second;
        fRoot["failures"][it->first.c_str()] = it->second;
    }
    SkDebugf("%d known, %d unknown\n", gKnown, totalUnknowns);
    fRoot["totalFailures"] = totalUnknowns;
    fRoot["totalSuccesses"] = gKnown;
    if (totalUnknowns > 0) {
        if (!FLAGS_failuresJsonPath.isEmpty()) {
            SkDebugf("Writing failures to %s\n", FLAGS_failuresJsonPath[0]);
            SkFILEWStream stream(FLAGS_failuresJsonPath[0]);
            stream.writeText(Json::StyledWriter().write(fRoot).c_str());
            stream.flush();
        }
        return -1;
    }
    return 0;
}
예제 #3
0
int
main(int argc, char **argv)
{
    if (argc != 2) {
        fprintf(stderr, "Usage: %s interface\n", argv[0]);
        return 1;
    }
    return sniff(argv[1]) ? 0 : 1;
}
예제 #4
0
bool UT_XML::sniff (const UT_ByteBuf * pBB, const char * xml_type)
{
  UT_ASSERT (pBB);
  UT_ASSERT (xml_type);

  if ((pBB == 0) || (xml_type == 0)) return false;

  const char * buffer = reinterpret_cast<const char *>(pBB->getPointer (0));
  UT_uint32 length = pBB->getLength ();

  return sniff (buffer, length, xml_type);
}
예제 #5
0
void read_wifi(struct params *p)
{
	char buf[4096];
	int rc;
	struct ieee80211_frame *wh;

	rc = sniff(p->rx, buf, sizeof(buf));
	if (rc == -1)
		err(1, "sniff()");
        
	wh = get_wifi(buf, &rc);
	if (!wh)
		return;

	/* filter my own shit */
	if (memcmp(wh->i_addr2, p->mac, 6) == 0) {
		/* XXX CTL frames */
		if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) !=
		    IEEE80211_FC0_TYPE_CTL)
			return;
	}

#if 1
	ack(p, wh);
#endif

	if (duplicate(p, wh, rc)) {
#if 0
		printf("Dup\n");
#endif		
		return;
	}

	switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
	case IEEE80211_FC0_TYPE_MGT:
		read_mgt(p, wh, rc);
		break;
		
	case IEEE80211_FC0_TYPE_CTL:
		read_ctl(p, wh, rc);
		break;
	
	case IEEE80211_FC0_TYPE_DATA:
		read_data(p, wh, rc);
		break;
	
	default:
		printf("wtf\n");
		abort();
		break;
	}
}
예제 #6
0
파일: expand.c 프로젝트: 2asoft/freebsd
void read_wifi(struct params *p)
{
	static char *buf = 0;
	static int buflen = 4096;
	struct ieee80211_frame *wh;
	int rc;

	if (!buf) {
		buf = (char*) malloc(buflen);
		if (!buf)
			err(1, "malloc()");
	}
	
	rc = sniff(p->rx, buf, buflen);
	if (rc == -1)
		err(1, "sniff()");

	wh = get_wifi(buf, &rc);
	if (!wh)
		return;

	/* relayed macast */
	if (frame_type(wh, IEEE80211_FC0_TYPE_DATA,
		       IEEE80211_FC0_SUBTYPE_DATA) &&
	    (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
	    (memcmp(wh->i_addr2, p->ap, 6) == 0) &&
	    (memcmp(wh->i_addr1, p->mcast, 5) == 0) &&
	    (memcmp(p->mac, wh->i_addr3, 6) == 0)) {
		got_mcast(p, wh, rc);
		return;
	}

	/* data */
	if (frame_type(wh, IEEE80211_FC0_TYPE_DATA,
		       IEEE80211_FC0_SUBTYPE_DATA)) {
		if (!wanted(p, wh, rc))
			return;
		
		enque(p, &buf, wh, rc);
		if (p->state == S_START)
			send_queue(p);
		return;
	}
}
예제 #7
0
/******************************
 * 		MAIN 			
 ******************************/
int main(int argc, char **argv) {

	/* ziskanie parametrov */
	get_params(argc, argv);
	
	/* funkcie na odchytenie ukoncujuceho signalu pre cyklus pcap_loop */
	signal(SIGQUIT, signal_handler);
	signal(SIGINT, signal_handler);
	signal(SIGTERM, signal_handler);

    /* monitorovanie hlaviciek HTTP */
	sniff();	
	
	/* zapisanie ziskanych informaci */
	write_XML();

	/* uvolnenie alokovanej pamate */
	dispose();

	/* uspesny koniec programu */
	exit(0);
}
예제 #8
0
int main(int argc, char *argv[]) {
  int sockfd_snd, sockfd_rcv_sender, sockfd_rcv_monitor, sockfd_monitor=-1;
  struct sockaddr_in my_addr;   // my address information
  struct sockaddr_in their_addr; // connector's address information
  fd_set read_fds_copy, write_fds_copy;
  socklen_t sin_size;
  struct timeval start_tv, left_tv;
  int yes=1;//, flag_send_monitor=0;
  struct timeval packet_deadline;
  struct in_addr addr;
  int flag_measure=0;
  char ch;
  unsigned short standalone_port = SENDER_PORT;
  // Do we use live data? Or previously recorded data?
  FILE * logfile = NULL;
  unsigned long quantum_no=0;
  int logflags = LOG_NOTHING;
  int select_count = 0;

  gettimeofday(&packet_deadline, NULL);

  init();

  //set up debug flag
  if (getenv("Debug")!=NULL)
    flag_debug=1;
  else
    flag_debug=0;
  flag_standalone = 0;

  /*
   * Process command-line arguments
   */
  while ((ch = getopt(argc,argv,"df:l:b:rst")) != -1) {
    switch (ch) {
      case 'd':
        flag_debug = 1; break;
      case 'f':
        if (logfile == NULL)
        {
          logfile = fopen(optarg, "a");
          if (logfile == NULL)
          {
            perror("Log fopen()");
            exit(1);
          }
        }
        break;
      case 'b':
        if (strcmp(optarg, "average") == 0)
        {
          bandwidth_method = BANDWIDTH_AVERAGE;
        } else if (strcmp(optarg, "max") == 0) {
          bandwidth_method = BANDWIDTH_MAX;
        } else if (strcmp(optarg, "vegas") == 0) {
          bandwidth_method = BANDWIDTH_VEGAS;
        } else if (strcmp(optarg, "buffer") == 0) {
          bandwidth_method = BANDWIDTH_BUFFER;
        } else {
          fprintf(stderr, "Unknown bandwidth method\n");
          usage();
          exit(1);
        }
        break;
      case 'l':
        if (strcmp(optarg, "everything") == 0)
        {
          logflags = LOG_EVERYTHING;
        }
        else if (strcmp(optarg, "nothing") == 0)
        {
          logflags = LOG_NOTHING;
        }
        else if (strcmp(optarg, "control-send") == 0)
        {
          logflags = logflags | CONTROL_SEND;
        }
        else if (strcmp(optarg, "control-receive") == 0)
        {
          logflags = logflags | CONTROL_RECEIVE;
        }
        else if (strcmp(optarg, "tcptrace-send") == 0)
        {
          logflags = logflags | TCPTRACE_SEND;
        }
        else if (strcmp(optarg, "tcptrace-receive") == 0)
        {
          logflags = logflags | TCPTRACE_RECEIVE;
        }
        else if (strcmp(optarg, "sniff-send") == 0)
        {
          logflags = logflags | SNIFF_SEND;
        }
        else if (strcmp(optarg, "sniff-receive") == 0)
        {
          logflags = logflags | SNIFF_RECEIVE;
        }
        else if (strcmp(optarg, "peer-write") == 0)
        {
          logflags = logflags | PEER_WRITE;
        }
        else if (strcmp(optarg, "peer-read") == 0)
        {
          logflags = logflags | PEER_READ;
        }
        else if (strcmp(optarg, "main-loop") == 0)
        {
          logflags = logflags | MAIN_LOOP;
        }
        else if (strcmp(optarg, "lookup-db") == 0)
        {
          logflags = logflags | LOOKUP_DB;
        }
        else if (strcmp(optarg, "delay-detail") == 0)
        {
            logflags = logflags | DELAY_DETAIL;
        }
        else if (strcmp(optarg, "packet-buffer-detail") == 0)
        {
            logflags = logflags | PACKET_BUFFER_DETAIL;
        }
        else
        {
            fprintf(stderr, "Unknown logging option %s\n", optarg);
            usage();
            exit(1);
        }
        break;
      case 's':
        flag_standalone = 1; break;
      case 'r':
        flag_standalone = 1;
        is_live = 0;
        break;
      case 't':
        flag_testmode = 1; break;
      default:
        fprintf(stderr,"Unknown option %c\n",ch);
        usage(); exit(1);
    }
  }
  argc -= optind;
  argv += optind;

  if (logfile == NULL)
  {
    logfile = stderr;
  }

  logInit(logfile, logflags, 1);

  if (flag_standalone) {
    if (argc != 3) {
      fprintf(stderr,"Wrong number of options for standalone: %i\n",argc);
      usage();
      exit(1);
    } else {
      flag_measure = 1;
//      rcvdb[0].valid = 1;
      standalone_port = atoi(argv[2]);
      inet_aton(argv[1], &addr);
      insert_fake(addr.s_addr, standalone_port);
//      rcvdb[0].ip    =  addr.s_addr;
//      rcvdb[0].sockfd= -1; //show error if used
//      rcvdb[0].last_usetime = time(NULL);
    }
    printf("Running in standalone mode\n");
  } else {
    if (argc != 1) {
      fprintf(stderr,"Wrong number of options: %i\n",argc);
      usage();
      exit(1);
    }
  }

  if (flag_testmode) {
      printf("Running in testmode\n");
      test_state = TEST_NOTSTARTED;
  }

  if (strlen(argv[0]) > 127) {
    fprintf(stderr,"Error: the <sniff-interface> name must be less than 127 characters \n");
    exit(1);
  }

//  strcpy(sniff_interface, argv[0]);


  //set up the sender connection listener
  if ((sockfd_rcv_sender = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    exit(1);
  }
  if (setsockopt(sockfd_rcv_sender, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
    perror("setsockopt");
    exit(1);
  }
  my_addr.sin_family = AF_INET;           // host byte order
  my_addr.sin_port = htons(SENDER_PORT);  // short, network byte order
  my_addr.sin_addr.s_addr = INADDR_ANY;   // automatically fill with my IP
//  memset(&(my_addr.sin_zero), '\0', 8);   // zero the rest of the struct
  if (flag_debug) printf("Listen on %s\n",inet_ntoa(my_addr.sin_addr));
  if (bind(sockfd_rcv_sender, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
    perror("bind");
    exit(1);
  }
  if (listen(sockfd_rcv_sender, PENDING_CONNECTIONS) == -1) {
    perror("listen");
    exit(1);
  }

  //set up the monitor connection listener
  if ((sockfd_rcv_monitor = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    exit(1);
  }
  if (setsockopt(sockfd_rcv_monitor, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
    perror("setsockopt");
    exit(1);
  }
  my_addr.sin_family = AF_INET;           // host byte order
  my_addr.sin_port = htons(MONITOR_PORT); // short, network byte order
  my_addr.sin_addr.s_addr = INADDR_ANY;   // automatically fill with my IP
//  memset(&(my_addr.sin_zero), '\0', 8);   // zero the rest of the struct
  if (flag_debug) printf("Listen on %s\n",inet_ntoa(my_addr.sin_addr));
  if (bind(sockfd_rcv_monitor, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
    perror("bind");
    exit(1);
  }
  if (listen(sockfd_rcv_monitor, 1) == -1) {
    perror("listen");
    exit(1);
  }

  //initialization
  packet_buffer_init();
  init_random_buffer();
  init_pcap(SNIFF_TIMEOUT, standalone_port, argv[0]);
  FD_ZERO(&read_fds);
  FD_ZERO(&read_fds_copy);
  FD_ZERO(&write_fds);
  FD_ZERO(&write_fds_copy);
  FD_SET(pcapfd,  &read_fds);
  FD_SET(sockfd_rcv_sender,  &read_fds);
  FD_SET(sockfd_rcv_monitor, &read_fds);
  maxfd = pcapfd; //socket order
  sin_size = sizeof(struct sockaddr_in);

  //main loop - the stubd runs forever
  while (1) {
//    flag_send_monitor=0; //reset flag for each quanta
    gettimeofday(&start_tv, NULL); //reset start time for each quanta

//    printf("Total: %d\n", total_size);
//    printf("========== Quantum %lu ==========\n", quantum_no);
    logWrite(MAIN_LOOP, NULL, "Quantum %lu", quantum_no);
    if (is_live)
    {
        update_stats();
        logWrite(MAIN_LOOP, NULL, "PCAP Received: %u Dropped: %u",
                 received_stat(), dropped_stat());
    }
    quantum_no++;

    //while in a quanta
    while(have_time(&start_tv, &left_tv)) {
      read_fds_copy  = read_fds;
      write_fds_copy = write_fds;

      select_count = select(maxfd+1, &read_fds_copy, &write_fds_copy, NULL,
                            &left_tv);
      if (select_count == -1)
      {
        perror("select");
        clean_exit(1);
      }
//      fprintf(stderr, "Select count: %d\n", select_count);
      // Send out packets to our peers if the deadline has passed.
//      logWrite(MAIN_LOOP, NULL, "Send normal packets to peers");
      handle_packet_buffer(&packet_deadline, &write_fds_copy);

      // send to destinations which are writeable and are behind.
//      logWrite(MAIN_LOOP, NULL, "Send pending packets to peers");
#ifdef USE_PACKET_BUFFER
      for_each_pending(try_pending, &write_fds_copy);
#endif

      // receive from existing senders
//      logWrite(MAIN_LOOP, NULL, "Receive packets from peers");
      for_each_readable_sender(receive_sender, &read_fds_copy);

/*
      //receive from existent senders
      for (i=0; i<CONCURRENT_SENDERS; i++){
        // Send pending data if it exists.
        if (snddb[i].valid==1 && FD_ISSET(snddb[i].sockfd, &read_fds_copy)) {
          receive_sender(i);
        }
      }
*/
      //handle new senders
      if (FD_ISSET(sockfd_rcv_sender, &read_fds_copy)) {
        if ((sockfd_snd = accept(sockfd_rcv_sender, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
          perror("accept");
          continue;
        } else {
          logWrite(MAIN_LOOP, NULL, "Accept new peer (%s)",
                   inet_ntoa(their_addr.sin_addr));
          replace_sender_by_stub_port(their_addr.sin_addr.s_addr,
                                      ntohs(their_addr.sin_port), sockfd_snd,
                                      &read_fds);
//        insert_db(their_addr.sin_addr.s_addr, their_addr.sin_port,
//                  SENDER_PORT, sockfd_snd, 1); //insert snddb
//        FD_SET(sockfd_snd, &read_fds); // add to master set
//        if (sockfd_snd > maxfd) { // keep track of the maximum
//          maxfd = sockfd_snd;
//        }
          if (flag_debug) printf("server: got connection from %s\n",inet_ntoa(their_addr.sin_addr));
        }
      }

      //handle the new monitor
      if (FD_ISSET(sockfd_rcv_monitor, &read_fds_copy)) {
        if ((sockfd_monitor = accept(sockfd_rcv_monitor, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
          perror("accept");
          continue;
        } else {
          int nodelay = 1;
          int nodelay_error = setsockopt(sockfd_monitor, IPPROTO_TCP,
                                         TCP_NODELAY, &nodelay,
                                         sizeof(nodelay));
          if (nodelay_error == -1)
          {
            perror("setsockopt (TCP_NODELAY)");
            clean_exit(1);
          }
          logWrite(MAIN_LOOP, NULL, "Accept new monitor (%s)",
                   inet_ntoa(their_addr.sin_addr));

          FD_CLR(sockfd_rcv_monitor, &read_fds);  //allow only one monitor connection
          FD_SET(sockfd_monitor, &read_fds);  //check the monitor connection for read
//        FD_SET(sockfd_monitor, &write_fds); //check the monitor connection for write
          if (sockfd_monitor > maxfd) { //keep track of the maximum
            maxfd = sockfd_monitor;
          }
          if (flag_debug) printf("server: got connection from %s\n",inet_ntoa(their_addr.sin_addr));
        }
      }

      //receive from the monitor
      if (sockfd_monitor!=-1 && FD_ISSET(sockfd_monitor, &read_fds_copy)) {
        logWrite(MAIN_LOOP, NULL, "Receive control message from monitor");
        if (receive_monitor(sockfd_monitor, &packet_deadline) == 0) { //socket_monitor closed by peer
          FD_CLR(sockfd_monitor, &read_fds); //stop checking the monitor socket
//        FD_CLR(sockfd_monitor, &write_fds);
          sockfd_monitor = -1;
          FD_SET(sockfd_rcv_monitor, &read_fds); //start checking the receiver control socket
          if (sockfd_rcv_monitor > maxfd) { // keep track of the maximum
            maxfd = sockfd_rcv_monitor;
          }
        }
      }

      //sniff packets
      if (FD_ISSET(pcapfd, &read_fds_copy)) {
        logWrite(MAIN_LOOP, NULL, "Sniff packet stream");
        sniff();
      }

    } //while in quanta

    //send measurements to the monitor once in each quanta
    if (sockfd_monitor!=-1)
// && FD_ISSET(sockfd_monitor, &write_fds_copy)) {
    {
        logWrite(MAIN_LOOP, NULL, "Send control message to monitor");
        if (send_monitor(sockfd_monitor) == 0) { //socket_monitor closed by peer
            logWrite(MAIN_LOOP, NULL, "Message to monitor failed");
            FD_CLR(sockfd_monitor, &read_fds); //stop checking the monitor socket
//        FD_CLR(sockfd_monitor, &write_fds);
            sockfd_monitor = -1;
            FD_SET(sockfd_rcv_monitor, &read_fds); //start checking the receiver control socket
            if (sockfd_rcv_monitor > maxfd) { // keep track of the maximum
                maxfd = sockfd_rcv_monitor;
            }
        } else {
            logWrite(MAIN_LOOP, NULL, "Message to monitor succeeded");
//        flag_send_monitor=1;
        }
    }

    // In testmode, we only start printing in the quanta we first see a packet
    if (flag_standalone) {
      print_measurements();
    }

    // If running in testmode, and the test is over, exit!
    if (flag_testmode && test_state == TEST_DONE) {
      printf("Test done - total bytes transmitted: %llu\n",total_bytes);
      break;
    }
  } //while forever

  packet_buffer_cleanup();

  return 0;
}
예제 #9
0
파일: Sniffer.c 프로젝트: JayFeng0225/moly
int main(int argc, char *argv[]) {
	char *in_if = NULL;
	char *out_if = NULL;
	char *in_file = NULL;
	char *out_file = NULL;
	TableStateMachine *machine;
	char *patterns = NULL;
	int i;
	char *param, *arg;
	int auto_mode, no_report, batch, max_rules;
	int num_workers;


	// ************* BEGIN DEBUG
	//struct pcap_pkthdr pkthdr;
	//char pkt[2048];
	//ProcessorData *processor;
	// ************* END


	auto_mode = 0;
	no_report = 0;
	num_workers = 1;
	batch = 0;
	max_rules = 0;

	if (argc > 1) {
		for (i = 1; i < argc; i++) {
			param = strsep(&argv[i], "=");
			arg = argv[i];
			if (strcmp(param, "in") == 0) {
				in_if = arg;
			} else if (strcmp(param, "out") == 0) {
				out_if = arg;
			} else if (strcmp(param, "infile") == 0) {
				in_file = arg;
			} else if (strcmp(param, "outfile") == 0) {
				out_file = arg;
			} else if (strcmp(param, "rules") == 0) {
				patterns = arg;
			} else if (strcmp(param, "max") == 0) {
				max_rules = atoi(arg);
			} else if (strcmp(param, "workers") == 0) {
				num_workers = atoi(arg);
			} else if (strcmp(param, "noreport") == 0) {
				no_report = 1;
			} else if (strcmp(param, "batch") == 0) {
				batch = 1;
			} else if (strcmp(param, "auto") == 0) {
				auto_mode = 1;
				break;
			}
		}
	}

	if (auto_mode == 0 && ((in_if == NULL && in_file == NULL) || (out_if == NULL && out_file == NULL) || patterns == NULL || max_rules < 0 || num_workers < 1)) {
		// Show usage
		fprintf(stderr, USAGE, argv[0]);
		exit(1);
	} else if (auto_mode == 1) {
		// Set defaults
		in_if = "eth0:1";
		out_if = "eth0:2";
		patterns = "../../SnortPatternsFull2.json";
		max_rules = 0;
		num_workers = 1;
	}

	machine = generateTableStateMachine(patterns, max_rules, 0);

	// ************* BEGIN DEBUG
	//void process_packet(unsigned char *arg, const struct pcap_pkthdr *pkthdr, const unsigned char *packetptr)
	//processor = init_processor(machine, NULL, NULL, 0);
	//strcpy(pkt,"008g");
	//process_packet((unsigned char *)processor, &pkthdr, (unsigned char*)pkt);
	// ************* END


	sniff(in_if, out_if, in_file, out_file, machine, num_workers, no_report, batch);

	return 0;
}
예제 #10
0
int main(int argc, char *argv[])
{
    int retval = EXIT_FAILURE;
    int long_opt_index = 0, display_info = 0, display_public_cert = 0, update_db = 0, quiet = 0;
    char c = 0;
    char *pcap_filter = NULL, *pcap_file = NULL, *pcap_interface = NULL, *update_db_outfile = NULL;
    struct keymaster certinfo = { 0 };
    struct option long_options[] = {
        { "fingerprint", required_argument, NULL, 'f' },
        { "pem", required_argument, NULL, 'p'  },
        { "host", required_argument, NULL, 'r' },
        { "pcap", required_argument, NULL, 'c' },
        { "interface", required_argument, NULL, 'i' },
        { "search", required_argument, NULL, 's' },
        { "filter", required_argument, NULL, 'l' },
        { "keypair", no_argument, NULL, 'k' },
        { "info", no_argument, NULL, 'v' },
        { "quiet", no_argument, NULL, 'q' },
        { "update", optional_argument, NULL, 'u' },
        { "help", no_argument, NULL, 'h' },
        { 0,    0,    0,    0   }
    };
    char *short_options = "f:p:r:c:i:s:l:u::kvqh";

    if(argc < MIN_ARGS)
    {
        usage(argv[0]);
        goto end;
    }

    while((c = getopt_long(argc,argv,short_options, long_options, &long_opt_index)) != -1)
    {
        switch(c)
        {
        case 'c':
            if(optarg) pcap_file = strdup(optarg);
            break;
        case 'f':
            if(optarg) certinfo.fingerprint = strdup(optarg);
            break;
        case 'p':
            if(optarg) certinfo.fingerprint = fingerprint_pem_file(optarg);
            break;
        case 'r':
            if(optarg) certinfo.fingerprint = fingerprint_host(optarg);
            break;
        case 'i':
            if(optarg) pcap_interface = strdup(optarg);
            break;
        case 'l':
            if(optarg) pcap_filter = strdup(optarg);
            break;
        case 's':
            if(optarg) print_search_results(optarg);
            break;
        case 'u':
            update_db = 1;
            if(optarg) update_db_outfile = strdup(optarg);
            else update_db_outfile = strdup(DB_NAME);
            break;
        case 'k':
            display_public_cert = 1;
            break;
        case 'v':
            display_info = 1;
            break;
        case 'q':
            quiet = 1;
            break;
        default:
            usage(argv[0]);
            goto end;
        }
    }

    /* Update the certificate database */
    if(update_db)
    {
        fprintf(stderr, "Updating %s from %s...", update_db_outfile, DB_UPDATE_URL);
        if(!update_database(DB_UPDATE_URL, update_db_outfile))
        {
            fprintf(stderr, "update failed!\n");
            goto end;
        } else {
            fprintf(stderr, "done.\n");
            goto success;
        }
    }

    /* If no filter was specified, use the default */
    if(pcap_filter == NULL)
    {
        pcap_filter = strdup(DEFAULT_FILTER);
    }

    /* Do raw traffic capture if specified */
    if(pcap_file != NULL)
    {
        certinfo.fingerprint = sniff(pcap_file, pcap_filter, PFILE);
    } else if(pcap_interface != NULL) {
        certinfo.fingerprint = sniff(pcap_interface, pcap_filter, IFACE);
    }

    /* Make sure we have a fingerprint */
    if(!certinfo.fingerprint)
    {
        fprintf(stderr, "No suitable certificate fingerprint provided!\n");
        goto end;
    }

    /* Try to lookup the private key that corresponds to this certificate */
    if(!lookup_key(&certinfo) || certinfo.key == NULL)
    {
        fprintf(stderr, "ERROR: Failed to locate a matching private certificate for fingerprint: %s\n", certinfo.fingerprint);
        goto end;
    }

    /* Display private key */
    if(!quiet)
    {
        printf("%s\n", certinfo.key);
    }

    /* Display public key */
    if(display_public_cert)
    {
        printf("%s\n", certinfo.certificate);
    }

    /* Show all certificate info for this cert */
    if(display_info)
    {
        print_all_cert_info(&certinfo);
    }

success:
    retval = EXIT_SUCCESS;
end:
    free_key(&certinfo);
    if(update_db_outfile) free(update_db_outfile);
    if(pcap_file) free(pcap_file);
    if(pcap_interface) free(pcap_interface);
    if(pcap_filter) free(pcap_filter);
    return retval;
}