Пример #1
0
Файл: dag.c Проект: DPMI/mp
void* dag_legacy_capture(void* ptr){
	struct CI* CI = (struct CI*)ptr;
	struct dag_context cap;
	capture_init(CI, &cap.base);

	logmsg(verbose, CAPTURE, "CI[%d] initializing capture on %s using DAGv1 (memory at %p).\n", CI->id, cap.base.iface, &datamem[CI->id]);

	if ( !setup_device(CI) ){
		/* error already show */
		return NULL;
	}

	cap.fd = CI->sd;
	cap.buffer = dag_mmap(CI->sd);
	cap.top = 0;
	cap.bottom = 0;

	/* setup callbacks */
	cap.base.init = (init_callback)dagcapture_init;
	cap.base.destroy = (destroy_callback)dagcapture_destroy;
	cap.base.read_packet = (read_packet_callback)legacy_read_packet;

	/* start capture */
	capture_loop(CI, (struct capture_context*)&cap);
	return NULL;
}
Пример #2
0
Файл: dag.c Проект: DPMI/mp
void* dag_capture(void* ptr){
	struct CI* CI = (struct CI*)ptr;
	struct dag_context cap;
	capture_init(CI, &cap.base);

	logmsg(verbose, CAPTURE, "CI[%d] initializing capture on %s using DAGv2 (memory at %p).\n", CI->id, cap.base.iface, CI->buffer);

	if ( !setup_device(CI) ){
		/* error already show */
		return NULL;
	}

	cap.fd = CI->sd;
	cap.buffer = NULL; /* not used by this driver */
	cap.top = NULL;
	cap.bottom = NULL;

	/* setup callbacks */
	if ( dag_mode == 0 ){
		cap.base.init = (init_callback)dagcapture_init_rxtx;
		cap.base.destroy = (destroy_callback)dagcapture_destroy_rxtx;
		cap.base.read_packet = (read_packet_callback)read_packet_rxtx;
	} else if ( dag_mode == 1 ){
		cap.base.init = (init_callback)dagcapture_init_wiretap;
		cap.base.destroy = (destroy_callback)dagcapture_destroy_wiretap;
		cap.base.read_packet = (read_packet_callback)read_packet_wiretap;
	} else {
		logmsg(stderr, CAPTURE, "Unsupported mode: %d\n", dag_mode);
		abort();
	}

	/* start capture */
	capture_loop(CI, (struct capture_context*)&cap);
	return NULL;
}
void FreqMeasureClass::begin(void)
{
	capture_init();
	capture_msw = 0;
	capture_previous = 0;
	buffer_head = 0;
	buffer_tail = 0;
	capture_start();
}
Пример #4
0
/* Closes libpcap during sleep period to avoid stale packet data in pcap buffer */
void pcap_sleep(int seconds)
{
    if(seconds > 0)
    {
        pcap_close(get_handle());
        set_handle(NULL);
        sleep(seconds);
        set_handle(capture_init(get_iface()));

        if(!get_handle())
        {
            cprintf(CRITICAL, "[-] Failed to re-initialize interface '%s'\n", get_iface());
        }
    }
}
Пример #5
0
/**
 * \brief Test the OV7740 initialization.
 *
 * \param test Current test case.
 */
static void ov7740_test_initialization_run(const struct test_case* const test)
{
	volatile uint32_t ul_error = 0;

	ul_error = capture_init();

	/* if initialization test failed, set g_ul_init_error_flag to avoid
	 * other tests to lock up */
	if (ul_error == 1) {
		g_ul_init_error_flag = true;
	}

	/* Check Result of the previous test */
	test_assert_true(test, ul_error == 0,
			"OV7740 initialization test failed!");
}
Пример #6
0
extern void capture_frame() {
  static bool inited = false;
  if (!inited) {
    capture_init();
    inited = true;
  }

  glBindTexture(GL_TEXTURE_2D, texids[frame]);
  glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 1280, 720, 0);

  frame = (frame + 1) % 10;

  static int cnt = 0;
  cnt++;
  if (cnt == 30) capture_dump_textures();
}
Пример #7
0
int main(int argc, char *argv[])
{
	int c = 0;
	FILE *fp = NULL;
	int long_opt_index = 0, i = 0, channel = 0, passive = 0, mode = 0;
	int source = INTERFACE, ret_val = EXIT_FAILURE;
	struct bpf_program bpf = { 0 };
	char *out_file = NULL, *last_optarg = NULL, *target = NULL, *bssid = NULL;
	char *short_options = "i:c:n:o:b:5sfuCDh";
        struct option long_options[] = {
		{ "bssid", required_argument, NULL, 'b' },
                { "interface", required_argument, NULL, 'i' },
                { "channel", required_argument, NULL, 'c' },
		{ "out-file", required_argument, NULL, 'o' },
		{ "probes", required_argument, NULL, 'n' },
		{ "daemonize", no_argument, NULL, 'D' },
		{ "file", no_argument, NULL, 'f' },
		{ "ignore-fcs", no_argument, NULL, 'C' },
		{ "5ghz", no_argument, NULL, '5' },
		{ "scan", no_argument, NULL, 's' },
		{ "survey", no_argument, NULL, 'u' },
                { "help", no_argument, NULL, 'h' },
                { 0, 0, 0, 0 }
        };

	fprintf(stderr, "\nWash v%s WiFi Protected Setup Scan Tool\n", PACKAGE_VERSION);
        fprintf(stderr, "Copyright (c) 2011, Tactical Network Solutions, Craig Heffner <*****@*****.**>\n\n");

	globule_init();
	sql_init();
	create_ap_table();
	set_auto_channel_select(0);
	set_wifi_band(BG_BAND);
	set_debug(INFO);
	set_validate_fcs(1);
	set_log_file(stdout);
	set_max_num_probes(DEFAULT_MAX_NUM_PROBES);

	while((c = getopt_long(argc, argv, short_options, long_options, &long_opt_index)) != -1)
        {
                switch(c)
                {
			case 'f':
				source = PCAP_FILE;
				break;
			case 'i':
				set_iface(optarg);
				break;
			case 'b':
				bssid = strdup(optarg);
				break;
			case 'c':
				channel = atoi(optarg);
				set_fixed_channel(1);
				break;
			case '5':
				set_wifi_band(AN_BAND);
				break;
			case 'n':
				set_max_num_probes(atoi(optarg));
				break;
			case 'o':
				out_file = strdup(optarg);
				break;
			case 's':
				mode = SCAN;
				break;
			case 'u':
				mode = SURVEY;
				break;
			case 'C':
				set_validate_fcs(0);
				break;
			case 'D':
				daemonize();
				break;
			default:
				usage(argv[0]);
				goto end;
		}

		/* Track the last optarg. This is used later when looping back through any specified pcap files. */
		if(optarg)
		{
			if(last_optarg)
			{
				free(last_optarg);
			}

			last_optarg = strdup(optarg);
		}
	}

	/* The interface value won't be set if capture files were specified; else, there should have been an interface specified */
	if(!get_iface() && source != PCAP_FILE)
	{
		usage(argv[0]);
		goto end;
	}

	if(get_iface() && source == PCAP_FILE)
	{
		cprintf(CRITICAL, "[X] ERROR: -i and -f options cannot be used together.\n");
		usage(argv[0]);
		goto end;
	}

	/* If we're reading from a file, be sure we don't try to transmit probe requests */
	if(source == PCAP_FILE)
	{
		passive = 1;
	}

	/* Open the output file, if any. If none, write to stdout. */
	if(out_file)
	{
		fp = fopen(out_file, "wb");
		if(!fp)
		{
			cprintf(CRITICAL, "[X] ERROR: Failed to open '%s' for writing\n", out_file);
			goto end;
		}

		set_log_file(fp);
	}

	/* 
	 * Loop through all of the specified capture sources. If an interface was specified, this will only loop once and the
	 * call to monitor() will block indefinitely. If capture files were specified, this will loop through each file specified
	 * on the command line and monitor() will return after each file has been processed.
	 */
	for(i=argc-1; i>0; i--)
	{
		/* If the source is a pcap file, get the file name from the command line */
		if(source == PCAP_FILE)
		{
			/* If we've gotten to the arguments, we're done */
			if((argv[i][0] == '-') ||
			   (last_optarg && (memcmp(argv[i], last_optarg, strlen(last_optarg)) == 0))
			)
			{
				break;
			}
			else
			{
				target = argv[i];
			}
		}
		/* Else, use the specified interface name */
		else
		{
			target = get_iface();
		}

		set_handle(capture_init(target));
		if(!get_handle())
		{
			cprintf(CRITICAL, "[X] ERROR: Failed to open '%s' for capturing\n", get_iface());
			goto end;
		}

		if(pcap_compile(get_handle(), &bpf, PACKET_FILTER, 0, 0) != 0)
		{
			cprintf(CRITICAL, "[X] ERROR: Failed to compile packet filter\n");
			goto end;
		}
		
		if(pcap_setfilter(get_handle(), &bpf) != 0)
		{
			cprintf(CRITICAL, "[X] ERROR: Failed to set packet filter\n");
			goto end;
		}

		/* Do it. */
		monitor(bssid, passive, source, channel, mode);
		printf("\n");
	}

	ret_val = EXIT_SUCCESS;

end:
	globule_deinit();
	sql_cleanup();
	if(bssid) free(bssid);
	if(out_file) free(out_file);
	if(wpsmon.fp) fclose(wpsmon.fp);
	return ret_val;
}
Пример #8
0
/**
 * @brief Main function logic
 *
 * Parse command line options and start running threads
 */
int
main(int argc, char* argv[])
{
    int opt, idx, limit, only_calls, no_incomplete, i;
    const char *device, *outfile;
    char bpf[512];
    const char *keyfile;
    const char *match_expr;
    int match_insensitive = 0, match_invert = 0;
    int no_interface = 0, quiet = 0, rtp_capture = 0;
    vector_t *infiles = vector_create(0, 1);

    // Program otptions
    static struct option long_options[] = {
        { "help", no_argument, 0, 'h' },
        { "version", no_argument, 0, 'V' },
        { "device", required_argument, 0, 'd' },
        { "input", required_argument, 0, 'I' },
        { "output", required_argument, 0, 'O' },
#if defined(WITH_GNUTLS) || defined(WITH_OPENSSL)
        { "keyfile", required_argument, 0, 'k' },
#endif
        { "calls", no_argument, 0, 'c' },
        { "rtp", no_argument, 0, 'r' },
        { "limit", no_argument, 0, 'l' },
        { "icase", no_argument, 0, 'i' },
        { "invert", no_argument, 0, 'v' },
        { "no-interface", no_argument, 0, 'N' },
        { "dump-config", no_argument, 0, 'D' },
#ifdef USE_EEP
        { "eep-listen", required_argument, 0, 'L' },
        { "eep-send", required_argument, 0, 'H' },
#endif
        { "quiet", no_argument, 0, 'q' },
    };

    // Initialize configuration options
    init_options();

    // Get initial values for configurable arguments
    device = setting_get_value(SETTING_CAPTURE_DEVICE);
    outfile = setting_get_value(SETTING_CAPTURE_OUTFILE);
    keyfile = setting_get_value(SETTING_CAPTURE_KEYFILE);
    limit = setting_get_intvalue(SETTING_CAPTURE_LIMIT);
    only_calls = setting_enabled(SETTING_SIP_CALLS);
    no_incomplete = setting_enabled(SETTING_SIP_NOINCOMPLETE);
    rtp_capture = setting_enabled(SETTING_CAPTURE_RTP);

    // Parse command line arguments
    opterr = 0;
    char *options = "hVd:I:O:pqtW:k:crl:ivNqDL:H:";
    while ((opt = getopt_long(argc, argv, options, long_options, &idx)) != -1) {
        switch (opt) {
        case 'h':
            usage();
            return 0;
        case 'V':
            version();
            return 0;
        case 'd':
            device = optarg;
            break;
        case 'I':
            vector_append(infiles, optarg);
            break;
        case 'O':
            outfile = optarg;
            break;
        case 'l':
            if(!(limit = atoi(optarg))) {
                fprintf(stderr, "Invalid limit value.\n");
                return 0;
            }
            break;
#if defined(WITH_GNUTLS) || defined(WITH_OPENSSL)
        case 'k':
            keyfile = optarg;
            break;
#endif
        case 'c':
            only_calls = 1;
            setting_set_value(SETTING_SIP_CALLS, SETTING_ON);
            break;
        case 'r':
            rtp_capture = 1;
            setting_set_value(SETTING_CAPTURE_RTP, SETTING_ON);
            break;
        case 'i':
            match_insensitive++;
            break;
        case 'v':
            match_invert++;
            break;
        case 'N':
            no_interface = 1;
            setting_set_value(SETTING_CAPTURE_STORAGE, "none");
            break;
        case 'q':
            quiet = 1;
            break;
        case 'D':
            key_bindings_dump();
            settings_dump();
            return 0;
        // Dark options for dummy ones
        case 'p':
        case 't':
        case 'W':
            break;
#ifdef USE_EEP
        case 'L':
            capture_eep_set_server_url(optarg);
            break;
        case 'H':
            capture_eep_set_client_url(optarg);
            break;
#endif
        case '?':
            if (strchr(options, optopt)) {
                fprintf(stderr, "-%c option requires an argument.\n", optopt);
            } else if (isprint(optopt)) {
                fprintf(stderr, "Unknown option -%c.\n", optopt);
            } else {
                fprintf(stderr, "Unknown option character '\\x%x'.\n", optopt);
            }
            return 1;
        default:
            break;
        }
    }

#if defined(WITH_GNUTLS) || defined(WITH_OPENSSL)
    // Set capture decrypt key file
    capture_set_keyfile(keyfile);
    // Check if we have a keyfile and is valid
    if (keyfile && !tls_check_keyfile(keyfile)) {
        fprintf(stderr, "%s does not contain a valid RSA private key.\n", keyfile);
        return 1;
    }
#endif

    // Check if given argument is a file
    if (argc == 2 && (access(argv[1], F_OK) == 0)) {
        // Old legacy option to open pcaps without other arguments
        printf("%s seems to be a file: You forgot -I flag?\n", argv[1]);
        return 0;
    }

    // Initialize SIP Messages Storage
    sip_init(limit, only_calls, no_incomplete);

    // Set capture options
    capture_init(limit, rtp_capture);

#ifdef USE_EEP
    // Initialize EEP if enabled
    capture_eep_init();
#endif

    // If we have an input file, load it
    if (vector_count(infiles)) {
        for (i = 0; i < vector_count(infiles); i++) {
            // Try to load file
            if (capture_offline(vector_item(infiles, i), outfile) != 0)
                return 1;
        }
    } else {
        // Check if all capture data is valid
        if (capture_online(device, outfile) != 0)
            return 1;
    }

    // Remove Input files vector
    vector_destroy(infiles);

    // More arguments pending!
    if (argv[optind]) {
        // Assume first pending argument is  match expression
        match_expr = argv[optind++];

        // Try to build the bpf filter string with the rest
        memset(bpf, 0, sizeof(bpf));
        for (i = optind; i < argc; i++)
            sprintf(bpf + strlen(bpf), "%s ", argv[i]);

        // Check if this BPF filter is valid
        if (capture_set_bpf_filter(bpf) != 0) {
            // BPF Filter invalid, check incluiding match_expr
            match_expr = 0;    // There is no need to parse all payload at this point


            // Build the bpf filter string
            memset(bpf, 0, sizeof(bpf));
            for (i = optind - 1; i < argc; i++)
                sprintf(bpf + strlen(bpf), "%s ", argv[i]);

            // Check bpf filter is valid again
            if (capture_set_bpf_filter(bpf) != 0) {
                fprintf(stderr, "Couldn't install filter %s: %s\n", bpf, capture_last_error());
                return 1;
            }
        }

        // Set the capture filter
        if (match_expr)
            if (sip_set_match_expression(match_expr, match_insensitive, match_invert)) {
                fprintf(stderr, "Unable to parse expression %s\n", match_expr);
                return 1;
            }
    }

    // Start a capture thread
    if (capture_launch_thread() != 0) {
        ncurses_deinit();
        fprintf(stderr, "Failed to launch capture thread.\n");
        return 1;
    }

    if (!no_interface) {
        // Initialize interface
        ncurses_init();
        // This is a blocking call.
        // Create the first panel and wait for user input
        ui_create_panel(PANEL_CALL_LIST);
        wait_for_input();
    } else {
        setbuf(stdout, NULL);
        while(capture_get_status() != CAPTURE_OFFLINE) {
            if (!quiet)
                printf("\rDialog count: %d", sip_calls_count());
            usleep(500 * 1000);
        }
        if (!quiet)
            printf("\rDialog count: %d\n", sip_calls_count());
    }

    // Capture deinit
    capture_deinit();

    // Deinitialize interface
    ncurses_deinit();

    // Deinitialize configuration options
    deinit_options();

    // Deallocate sip stored messages
    sip_deinit();

    // Leaving!
    return 0;
}
Пример #9
0
/* Brute force all possible WPS pins for a given access point */
void crack()
{
    unsigned char *bssid = NULL;
    char *pin = NULL;
    int fail_count = 0, loop_count = 0, sleep_count = 0, assoc_fail_count = 0;
    float pin_count = 0;
    time_t start_time = 0;
    enum wps_result result = 0;
    /* MAC CHANGER VARIABLES */
    int mac_changer_counter = 0;
    char mac[MAC_ADDR_LEN] = { 0 };
    unsigned char mac_string [] = "ZZ:ZZ:ZZ:ZZ:ZZ:ZZ";
    unsigned char* new_mac = &mac_string[0];
    char last_digit = '0';

    if(!get_iface())
    {
        return;
    }

    if(get_max_pin_attempts() == -1)
    {
        cprintf(CRITICAL, "[X] ERROR: This device has been blacklisted and is not supported.\n");
        return;
    }

    /* Initialize network interface */
    set_handle(capture_init(get_iface()));

    if(get_handle() != NULL)
    {
        generate_pins();

        /* Restore any previously saved session */
        if(get_static_p1() == NULL)
        {
            restore_session();
        }

        /* Convert BSSID to a string */
        bssid = mac2str(get_bssid(), ':');

        /*
         * We need to get some basic info from the AP, and also want to make sure the target AP
         * actually exists, so wait for a beacon packet
         */
        cprintf(INFO, "[+] Waiting for beacon from %s\n", bssid);
        read_ap_beacon();
        process_auto_options();

        /* I'm fairly certian there's a reason I put this in twice. Can't remember what it was now though... */
        if(get_max_pin_attempts() == -1)
        {
            cprintf(CRITICAL, "[X] ERROR: This device has been blacklisted and is not supported.\n");
            return;
        }

        /* This initial association is just to make sure we can successfully associate */
        while(!reassociate())
        {
            if(assoc_fail_count == MAX_ASSOC_FAILURES)
            {
                assoc_fail_count = 0;
                cprintf(CRITICAL, "[!] WARNING: Failed to associate with %s (ESSID: %s)\n", bssid, get_ssid());
            }
            else
            {
                assoc_fail_count++;
            }
        }
        cprintf(INFO, "[+] Associated with %s (ESSID: %s)\n", bssid, get_ssid());

        /* Used to calculate pin attempt rates */
        start_time = time(NULL);

        /* If the key status hasn't been explicitly set by restore_session(), ensure that it is set to KEY1_WIP */
        if(get_key_status() <= KEY1_WIP)
        {
            set_key_status(KEY1_WIP);
        }
        /*
         * If we're starting a session at KEY_DONE, that means we've already cracked the pin and the AP is being re-attacked.
         * Re-set the status to KEY2_WIP so that we properly enter the main cracking loop.
         */
        else if(get_key_status() == KEY_DONE)
        {
            set_key_status(KEY2_WIP);
        }

        //copy the current mac to the new_mac variable for mac changer
        if (get_mac_changer() == 1) {
            strncpy(new_mac, mac2str(get_mac(), ':'), 16);
        }

        /* Main cracking loop */
        for(loop_count=0, sleep_count=0; get_key_status() != KEY_DONE; loop_count++, sleep_count++)
        {
            //MAC Changer switch/case to define the last mac address digit
            if (get_mac_changer() == 1) {
                switch (mac_changer_counter) {
                case 0:
                    last_digit = '0';
                    break;
                case 1:
                    last_digit = '1';
                    break;
                case 2:
                    last_digit = '2';
                    break;
                case 3:
                    last_digit = '3';
                    break;
                case 4:
                    last_digit = '4';
                    break;
                case 5:
                    last_digit = '5';
                    break;
                case 6:
                    last_digit = '6';
                    break;
                case 7:
                    last_digit = '7';
                    break;
                case 8:
                    last_digit = '8';
                    break;
                case 9:
                    last_digit = '9';
                    break;
                case 10:
                    last_digit = 'A';
                    break;
                case 11:
                    last_digit = 'B';
                    break;
                case 12:
                    last_digit = 'C';
                    break;
                case 13:
                    last_digit = 'D';
                    break;
                case 14:
                    last_digit = 'E';
                    break;
                case 15:
                    last_digit = 'F';
                    mac_changer_counter = -1;
                    break;
                }

                mac_changer_counter++;

                new_mac[16] = last_digit;
                //transform the string to a MAC and define the MAC
                str2mac((unsigned char *) new_mac, (unsigned char *) &mac);
                set_mac((unsigned char *) &mac);

                cprintf(WARNING, "[+] Using MAC %s \n", mac2str(get_mac(), ':'));
            }

            /*
             * Some APs may do brute force detection, or might not be able to handle an onslaught of WPS
             * registrar requests. Using a delay here can help prevent the AP from locking us out.
             */
            pcap_sleep(get_delay());

            /* Users may specify a delay after x number of attempts */
            if((get_recurring_delay() > 0) && (sleep_count == get_recurring_delay_count()))
            {
                cprintf(VERBOSE, "[+] Entering recurring delay of %d seconds\n", get_recurring_delay());
                pcap_sleep(get_recurring_delay());
                sleep_count = 0;
            }

            /*
             * Some APs identify brute force attempts and lock themselves for a short period of time (typically 5 minutes).
             * Verify that the AP is not locked before attempting the next pin.
             */
            while(get_ignore_locks() == 0 && is_wps_locked())
            {
                cprintf(WARNING, "[!] WARNING: Detected AP rate limiting, waiting %d seconds before re-checking\n", get_lock_delay());
                pcap_sleep(get_lock_delay());

            }

            /* Initialize wps structure */
            set_wps(initialize_wps_data());
            if(!get_wps())
            {
                cprintf(CRITICAL, "[-] Failed to initialize critical data structure\n");
                break;
            }

            /* Try the next pin in the list */
            pin = build_next_pin();
            if(!pin)
            {
                cprintf(CRITICAL, "[-] Failed to generate the next payload\n");
                break;
            }
            else
            {
                cprintf(WARNING, "[+] Trying pin %s\n", pin);
            }

            /*
             * Reassociate with the AP before each WPS exchange. This is necessary as some APs will
             * severely limit our pin attempt rate if we do not.
             */
            assoc_fail_count = 0;
            while(!reassociate())
            {
                if(assoc_fail_count == MAX_ASSOC_FAILURES)
                {
                    assoc_fail_count = 0;
                    cprintf(CRITICAL, "[!] WARNING: Failed to associate with %s (ESSID: %s)\n", bssid, get_ssid());
                }
                else
                {
                    assoc_fail_count++;
                }
            }


            /*
             * Enter receive loop. This will block until a receive timeout occurs or a
             * WPS transaction has completed or failed.
             */
            result = do_wps_exchange();

            switch(result)
            {
            /*
             * If the last pin attempt was rejected, increment
             * the pin counter, clear the fail counter and move
             * on to the next pin.
             */
            case KEY_REJECTED:
                fail_count = 0;
                pin_count++;
                advance_pin_count();
                break;
            /* Got it!! */
            case KEY_ACCEPTED:
                break;
            /* Unexpected timeout or EAP failure...try this pin again */
            default:
                cprintf(VERBOSE, "[!] WPS transaction failed (code: 0x%.2X), re-trying last pin\n", result);
                fail_count++;
                break;
            }

            /* If we've had an excessive number of message failures in a row, print a warning */
            if(fail_count == WARN_FAILURE_COUNT)
            {
                cprintf(WARNING, "[!] WARNING: %d failed connections in a row\n", fail_count);
                fail_count = 0;
                pcap_sleep(get_fail_delay());
            }

            /* Display status and save current session state every DISPLAY_PIN_COUNT loops */
            if(loop_count == DISPLAY_PIN_COUNT)
            {
                save_session();
                display_status(pin_count, start_time);
                loop_count = 0;
            }

            /*
             * The WPA key and other settings are stored in the globule->wps structure. If we've
             * recovered the WPS pin and parsed these settings, don't free this structure. It
             * will be freed by wpscrack_free() at the end of main().
             */
            if(get_key_status() != KEY_DONE)
            {
                wps_deinit(get_wps());
                set_wps(NULL);
            }
            /* If we have cracked the pin, save a copy */
            else
            {
                set_pin(pin);
            }
            free(pin);
            pin = NULL;

            /* If we've hit our max number of pin attempts, quit */
            if((get_max_pin_attempts() > 0) &&
                    (pin_count == get_max_pin_attempts()))
            {
                cprintf(VERBOSE, "[+] Quitting after %d crack attempts\n", get_max_pin_attempts());
                break;
            }
        }

        if(bssid) free(bssid);
        if(get_handle())
        {
            pcap_close(get_handle());
            set_handle(NULL);
        }
    }
    else
    {
        cprintf(CRITICAL, "[-] Failed to initialize interface '%s'\n", get_iface());
    }
}
Пример #10
0
void  main()
{


	pid_t pID;
	char device[20];
	strcpy(device, "lo");
	//strcpy(device, "eth0");


	/** Time to split into two processes
	 *  1. the child Process is for capturing (incoming)
	 *  2. the parent process is for injecting frames (outgoing)
	 */
	pID = fork();

	if (pID == 0)  // child -- Capture process

	  {

		 // Code only executed by child process
		PRINT_DEBUG("child started to capture \n");
		//sleep(2);

		capture_init(device);

	   }

	   else if (pID < 0) // failed to fork

	   {

		   PRINT_DEBUG ("Failed to Fork \n");
		   exit(1);

	   }

	   else      // parent

	   {
		 // Code only executed by parent process

		   /** inject handler is supposed to be initialized earlier to make sure that forwarding
		   	 * feature is able to work even if the parent process did not start injecting yet
		   	 * we fix this by sleeping the capturing process for a while. To give the injection
		   	 * process a lead
		   	 */
			PRINT_DEBUG("parent started to Inject \n");
		   	inject_init(device);
		  // 	while (1);


	   }


		/**
			if (inject_handle != NULL);
				pcap_close(inject_handle);

			if (capture_handle != NULL);
				pcap_close(capture_handle);
		*/

		return;

}
Пример #11
0
/*
 * snd_thread_fn(arg) --
 *
 *   This is the main function for the background recording thread. It reads the
 *   captured samples in to a local buffer, and then copies it to the shared
 *   ring buffer for the other threads.
 *
 *   This function should never terminate during the lifetime of the server.
 *
 *   Arguments:
 *     - arg  Unused
 *
 *   Return value:
 *     Should never return
 */
static void *snd_thread_fn(void *arg)
{
	snd_pcm_t *pcmh = NULL;
	psize_t    psize;
	const int maxframes = 128;
	int local_bufsize, nperiods, nframes, tmpsz;
	int nbytes, towrite, ret;
	char *local_buffer  = NULL;

	LOG(2, "Sound thread created...\n");

	/*
	 * Initialize the audio hardware
	 */
	LOG(1, "Initializing capture device\n");
	if (capture_init(&pcmh, global_options.device, &psize) < 0) {
		fprintf(stderr, "Badness happened\n");
		abort();
	}

	LOG(3, "   Period size: %ld frames\n", psize.frames);
	LOG(3, "   Period time: %d us\n",      psize.us);

	/*
	 * Allocate the global buffer and the local buffer
	 */
	nperiods = (global_options.sndhistory * 1000000L) / psize.us;
	nframes  = nperiods  * psize.frames;
	tmpsz    = nframes   * 2 * 2; /* 2 chan/frame, 2 bytes/chan */
	local_bufsize = maxframes * 2 * 2;

	gbuffer      = malloc(tmpsz);
	local_buffer = malloc(local_bufsize);
	gbufsize     = tmpsz;
	gbufpos      = 0;

	if (!gbuffer || !local_buffer) {
		fprintf(stderr, "Bad alloc\n");
		abort();
	}

	/*
	 * Signal that we're done with initialization
	 */
	pthread_barrier_wait(&ginit_barrier);

	/*
	 * Start dumping the audio in to the global buffer
	 */
	LOG(1, "Beginning to capture audio...\n");
	while (1) {
		ret = snd_pcm_readi(pcmh, local_buffer, maxframes);

		if (ret == -EPIPE) {
			fprintf(stderr, "Buffer overrun\n");
			snd_pcm_prepare(pcmh);

		} else if (ret < 0) {
			fprintf(stderr, "Read error: %s\n", snd_strerror(ret));
			abort();

		} else  {
			nbytes = ret * 2 * 2;

			pthread_mutex_lock(&gbuflock);
			towrite = MIN(gbufsize - gbufpos, nbytes);
			memcpy(gbuffer + gbufpos, local_buffer, towrite);
			nbytes -= towrite;

			gbufpos  += towrite;
			if (nbytes) {
				/* Wrap around */
				memcpy(gbuffer, local_buffer + towrite, nbytes);
				gbufpos = nbytes;
				LOG(3, "Full audio buffer! Wrapping...\n");
			}
			pthread_mutex_unlock(&gbuflock);
		}
	}

	free(gbuffer);
	free(local_buffer);

	return NULL;
}
Пример #12
0
void  main()
{

  	(void) signal(SIGINT, termination_handler);
  	print_app_banner();


	// ADDED mrd015 !!!!! 
	// trying to put code from fins_ethernet.sh here. This should allow mkfifo to be called w/o building coreutils for android?
	
	printf("\n\nAttempting to make " FINS_TMP_ROOT "\n");
	if(system("mkdir " FINS_TMP_ROOT) != 0){
		printf(FINS_TMP_ROOT " already exists! Cleaning...\n");
		// if cannot create directory, assume it contains files and try to delete them
		if(system("cd " FINS_TMP_ROOT ";rm *") != 0){
			printf("Cannot remove files in " FINS_TMP_ROOT  "!\n");
		}else {
			printf(FINS_TMP_ROOT " was cleaned successfully.\n\n");
		}
	}

	if(mkfifo(INCOME_PIPE, 0777) != 0){
		PRINT_DEBUG("Failed to mkfifo(INCOME_PIPE, 0777)");
		exit(1);
	}

	if(mkfifo(INJECT_PIPE, 0777) != 0){
		PRINT_DEBUG("Failed to mkfifo(INJECT_PIPE, 0777)");
		exit(1);
	}
	//^^^^^END^^^^^ !!!!!	

	fflush(stdout);
	pid_t pID;
	char device[20];
	//strcpy(device, "lo"); //original !!!!!
	strcpy(device, "eth0"); //changed to this !!!!!
	//strcpy(device, "eth1"); //changed to this !!!!!
	//strcpy(device, "wlan0");


	/** Time to split into two processes
	 *  1. the child Process is for capturing (incoming)
	 *  2. the parent process is for injecting frames (outgoing)
	 */
	pID = fork();

	if (pID == 0)  // child -- Capture process

	{

		// Code only executed by child process
		PRINT_DEBUG("child started to capture \n");
		//sleep(2);

		capture_init(device);

	}

	else if (pID < 0) // failed to fork

	{

		PRINT_DEBUG ("Failed to Fork \n");
		exit(1);

	}

	else      // parent

	{
		// Code only executed by parent process

		/** inject handler is supposed to be initialized earlier to make sure that forwarding
		 * feature is able to work even if the parent process did not start injecting yet
		 * we fix this by sleeping the capturing process for a while. To give the injection
		 * process a lead
		 */
		PRINT_DEBUG("parent started to Inject \n");
		inject_init(device);
		// 	while (1);


	}


	/**
			if (inject_handle != NULL);
				pcap_close(inject_handle);

			if (capture_handle != NULL);
				pcap_close(capture_handle);
	 */

//	return;

}
Пример #13
0
uae_u8 sampler_getsample (int channel)
{
#if 0
	int cur_pos;
	static int cap_pos;
	static float diffsample;
#endif
	static double doffset_offset;
	HRESULT hr;
	DWORD t;
	void *p1, *p2;
	DWORD len1, len2;
	evt cycles;
	int sample, samplecnt;
	double doffset;
	int offset;

	if (!currprefs.sampler_stereo)
		channel = 0;

	if (!inited) {
		DWORD pos;
		if (!capture_init ()) {
			capture_free ();
			return 0;
		}
		inited = 1;
		oldcycles = get_cycles ();
		oldoffset = -1;
		doffset_offset = 0;
		hr = lpDSB2r->GetCurrentPosition (&t, &pos);
		if (FAILED (hr)) {
			sampler_free ();
			return 0;
		}		
		if (t >= pos)
			safediff = t - pos;
		else
			safediff = recordbufferframes * SAMPLESIZE - pos + t;
		write_log (_T("SAMPLER: safediff %d %d\n"), safediff, safediff + sampleframes * SAMPLESIZE);
		safediff += 4 * sampleframes * SAMPLESIZE;

#if 0
		diffsample = 0;
		safepos = -recordbufferframes / 10 * SAMPLESIZE;
		hr = lpDSB2r->GetCurrentPosition (&t, &pos);
		cap_pos = pos;
		cap_pos += safepos;
		if (cap_pos < 0)
			cap_pos += recordbufferframes * SAMPLESIZE;
		if (cap_pos >= recordbufferframes * SAMPLESIZE)
			cap_pos -= recordbufferframes * SAMPLESIZE;
		if (FAILED (hr)) {
			sampler_free ();
			return 0;
		}
#endif
	}
	if (clockspersample < 1)
		return 0;
	uae_s16 *sbuf = (uae_s16*)samplebuffer;

	vsynccnt = 0;
	sample = 0;
	samplecnt = 0;
	cycles = (int)get_cycles () - (int)oldcycles;
	doffset = doffset_offset + cycles / clockspersample;
	offset = (int)doffset;
	if (oldoffset < 0 || offset >= sampleframes || offset < 0) {
		if (offset >= sampleframes) {
			doffset -= offset;
			doffset_offset = doffset;
		}
		if (oldoffset >= 0 && offset >= sampleframes) {
			while (oldoffset < sampleframes) {
				sample += sbuf[oldoffset * SAMPLESIZE / 2 + channel];
				oldoffset++;
				samplecnt++;
			}
		}
		hr = lpDSB2r->GetCurrentPosition (&t, NULL);
		int pos = t;
		pos -= safediff;
		if (pos < 0)
			pos += recordbufferframes * SAMPLESIZE;
		hr = lpDSB2r->Lock (pos, sampleframes * SAMPLESIZE, &p1, &len1, &p2, &len2, 0);
		if (FAILED (hr)) {
			write_log (_T("SAMPLER: Lock() failed %x\n"), hr);
			return 0;
		}
		memcpy (samplebuffer, p1, len1);
		if (p2)
			memcpy (samplebuffer + len1, p2, len2);
		lpDSB2r->Unlock (p1, len1, p2, len2);

#if 0
		cap_pos = t;
		cap_pos += sampleframes * SAMPLESIZE;
		if (cap_pos < 0)
			cap_pos += RECORDBUFFER * SAMPLESIZE;
		if (cap_pos >= RECORDBUFFER * SAMPLESIZE)
			cap_pos -= RECORDBUFFER * SAMPLESIZE;

		hr = lpDSB2r->GetCurrentPosition (&t, &pos);
		cur_pos = pos;
		if (FAILED (hr))
			return 0;

		cur_pos += safepos;
		if (cur_pos < 0)
			cur_pos += RECORDBUFFER * SAMPLESIZE;
		if (cur_pos >= RECORDBUFFER * SAMPLESIZE)
			cur_pos -= RECORDBUFFER * SAMPLESIZE;

		int diff;
		if (cur_pos >= cap_pos)
			diff = cur_pos - cap_pos;
		else
			diff = RECORDBUFFER * SAMPLESIZE - cap_pos + cur_pos;
		if (diff > RECORDBUFFER * SAMPLESIZE / 2)
			diff -= RECORDBUFFER * SAMPLESIZE; 
		diff /= SAMPLESIZE;

		int diff2 = 100 * diff / (RECORDBUFFER / 2);
		diffsample = -pow (diff2 < 0 ? -diff2 : diff2, 3.1);
		if (diff2 < 0)
			diffsample = -diffsample;
		write_log (_T("%d\n"), diff);

		write_log (_T("CAP=%05d CUR=%05d (%-05d) OFF=%05d %f\n"),
			cap_pos / SAMPLESIZE, cur_pos / SAMPLESIZE, (cap_pos - cur_pos) / SAMPLESIZE, offset, doffset_offset);
#endif

		if (offset < 0)
			offset = 0;
		if (offset >= sampleframes)
			offset -= sampleframes;

		oldoffset = 0;
		oldcycles = get_cycles ();
	}

	while (oldoffset <= offset) {
		sample += sbuf[oldoffset * SAMPLESIZE / 2 + channel];
		samplecnt++;
		oldoffset++;
	}
	oldoffset = offset;

	if (samplecnt > 0)
		sample /= samplecnt;
#if 1
	 /* yes, not 256, without this max recording volume would still be too quiet on my sound cards */
	sample /= 128;
	if (sample < -128)
		sample = 0;
	else if (sample > 127)
		sample = 127;
	return (uae_u8)(sample - 128);
#else
	return (Uae_u8)((sample / 256) - 128);
#endif
}
Пример #14
0
int main(int argc, char *argv[])
{
        /** return value of main() */
        int res = 1;
        /* current configuration */
        LedPrefs *prefs = NULL;
	/* current setup */
	LedSetup *setup = NULL;
        /** framebuffer for captured image */
        LedFrame *frame = NULL;



        /* check binary version compatibility */
        NFT_LED_CHECK_VERSION


        /* set default loglevel to INFO */
	nft_log_level_set(L_INFO);


	/* initialize exit handlers */
	int signals[] = { SIGHUP, SIGINT, SIGQUIT, SIGABRT };
	unsigned int i;
	for(i=0; i<sizeof(signals)/sizeof(int); i++)
	{
		if(signal(signals[i], _exit_signal_handler) == SIG_ERR)
		{
			NFT_LOG_PERROR("signal()");
			goto _m_exit;
		}
	}



        /* default fps */
        _c.fps = 25;

        /* default mechanism */
        _c.method = METHOD_MIN+1;

        /* default config-filename */
        if(!led_prefs_default_filename(_c.prefsfile, sizeof(_c.prefsfile), ".ledcap.xml"))
                goto _m_exit;

        /* parse cmdline-arguments */
        if(!_parse_args(argc, argv))
                goto _m_exit;


	/* print welcome msg */
	NFT_LOG(L_INFO, "%s %s (c) D.Hiepler 2006-2012", PACKAGE_NAME, ledcap_version_long());
	NFT_LOG(L_VERBOSE, "Loglevel: %s", nft_log_level_to_string(nft_log_level_get()));



	/* initialize preferences context */
    	if(!(prefs = led_prefs_init()))
    		return -1;

	/* parse prefs-file */
    	LedPrefsNode *pnode;
    	if(!(pnode = led_prefs_node_from_file(_c.prefsfile)))
    	{
		NFT_LOG(L_ERROR, "Failed to open configfile \"%s\"",
		        		_c.prefsfile);
		goto _m_exit;
	}

        /* create setup from prefs-node */
    	if(!(setup = led_prefs_setup_from_node(prefs, pnode)))
    	{
		NFT_LOG(L_ERROR, "No valid setup found in preferences file.");
		led_prefs_node_free(pnode);
		goto _m_exit;
	}

    	/* free preferences node */
    	led_prefs_node_free(pnode);




        /* determine width of input-frames */
        LedFrameCord width, height;
        if((width = led_setup_get_width(setup)) > _c.width)
        {
                NFT_LOG(L_WARNING, "LED-Setup width (%d) > our width (%d). Using setup-value",
                        width,_c.width);
                /* use dimensions of mapped chain */
                _c.width = width;
        }

        /* determine height of input-frames */
        if((height = led_setup_get_height(setup)) > _c.height)
        {
                NFT_LOG(L_WARNING, "LED-Setup height (%d) > our height (%d). Using setup-value.",
                        height, _c.height);
                /* use dimensions of mapped chain */
                _c.height = height;
        }


        if(_c.width < 0)
        {
                NFT_LOG(L_ERROR, "width (%d) < 0", _c.width);
                goto _m_exit;
        }

        if(_c.height < 0)
        {
                NFT_LOG(L_ERROR, "height (%d) < 0", _c.height);
                goto _m_exit;
        }

        /* sanitize x-offset @todo check for maximum */
        if(_c.x < 0)
        {
                NFT_LOG(L_ERROR, "Invalid x coordinate: %d, using 0", _c.x);
                _c.x = 0;
        }

        /* sanitize y-offset @todo check for maximum */
        if(_c.y < 0)
        {
                NFT_LOG(L_ERROR, "Invalid y coordinate: %d, using 0", _c.y);
                _c.y = 0;
        }


        /* initialize capture mechanism (only imlib for now) */
        if(!capture_init(_c.method))
                goto _m_exit;

        /* allocate framebuffer */
        NFT_LOG(L_INFO, "Allocating frame: %dx%d (%s)",
	        _c.width, _c.height, capture_format());
        if(!(frame = led_frame_new(_c.width, _c.height, led_pixel_format_from_string(capture_format()))))
                goto _m_exit;

        /* respect endianess */
        led_frame_set_big_endian(frame, capture_is_big_endian());

        /* get first hardware */
        LedHardware *hw;
        if(!(hw = led_setup_get_hardware(setup)))
                goto _m_exit;

        /* initialize pixel->led mapping */
        if(!led_hardware_list_refresh_mapping(hw))
                goto _m_exit;

        /* precalc memory offsets for actual mapping */
        if(!led_chain_map_from_frame(led_hardware_get_chain(hw), frame))
                goto _m_exit;

        /* set saved gain to all registered hardware instances */
        if(!led_hardware_list_refresh_gain(hw))
                goto _m_exit;


	/* print some debug-info */
        led_frame_print(frame, L_VERBOSE);
        led_hardware_print(hw, L_VERBOSE);


        /* initially sample time for frametiming */
        if(!led_fps_sample())
                goto _m_exit;


        /* output some useful info */
        NFT_LOG(L_INFO, "Capturing %dx%d pixels at position x/y: %d/%d", _c.width, _c.height, _c.x, _c.y);

        /* loop until _c.running is set to FALSE */
        _c.running = TRUE;
        while(_c.running)
        {
                /* capture frame */
                if(!(capture_frame(frame, _c.x, _c.y)))
                        break;

                /* print frame for debugging */
                //led_frame_buffer_print(frame);

                /* map from frame */
                LedHardware *h;
                for(h = hw; h; h = led_hardware_list_get_next(h))
                {
                        if(!led_chain_fill_from_frame(led_hardware_get_chain(h), frame))
                        {
                                NFT_LOG(L_ERROR, "Error while mapping frame");
                                break;
                        }
                }


                /* send frame to hardware(s) */
                led_hardware_list_send(hw);

                /* delay in respect to fps */
                if(!led_fps_delay(_c.fps))
                        break;

                /* show frame */
                led_hardware_list_show(hw);

                /* save time when frame is displayed */
                if(!led_fps_sample())
                        break;
        }



        /* mark success */
        res = 0;

_m_exit:
        /* deinitialize capture mechanism */
        capture_deinit();

	/* free frame */
        led_frame_destroy(frame);

	/* destroy config */
        led_setup_destroy(setup);

	/* destroy config */
        led_prefs_deinit(prefs);


        return res;
}
Пример #15
0
int main(int argc, char *argv[])
{
   /*
    * Alloc the global structures
    * We can access these structs via the macro in ec_globals.h
    */
        
   globals_alloc();
  
   GBL_PROGRAM = strdup(EC_PROGRAM);
   GBL_VERSION = strdup(EC_VERSION);
   SAFE_CALLOC(GBL_DEBUG_FILE, strlen(EC_PROGRAM) + strlen(EC_VERSION) + strlen("_debug.log") + 1, sizeof(char));
   sprintf(GBL_DEBUG_FILE, "%s%s_debug.log", GBL_PROGRAM, EC_VERSION);
   
   DEBUG_INIT();
   DEBUG_MSG("main -- here we go !!");

   /* initialize the filter mutex */
   filter_init_mutex();
   
   /* register the main thread as "init" */
   ec_thread_register(EC_PTHREAD_SELF, "init", "initialization phase");
   
   /* activate the signal handler */
   signal_handler();
   
   /* ettercap copyright */
   fprintf(stdout, "\n" EC_COLOR_BOLD "%s %s" EC_COLOR_END " copyright %s %s\n\n", 
         GBL_PROGRAM, GBL_VERSION, EC_COPYRIGHT, EC_AUTHORS);
   
   /* getopt related parsing...  */
   parse_options(argc, argv);

   /* check the date */
   time_check();

   /* load the configuration file */
   load_conf();
   
   /* 
    * get the list of available interfaces 
    * 
    * this function will not return if the -I option was
    * specified on command line. it will instead print the
    * list and exit
    */
   capture_getifs();
   
   /* initialize the user interface */
   ui_init();
   
   /* initialize libpcap */
   capture_init();

   /* initialize libnet (the function contain all the checks) */
   send_init();
 
   /* get hardware infos */
   get_hw_info();
 
   /* 
    * always disable the kernel ip forwarding (except when reading from file).
    * the forwarding will be done by ettercap.
    */
   if (!GBL_OPTIONS->read && !GBL_OPTIONS->unoffensive && !GBL_OPTIONS->only_mitm)
      disable_ip_forward();
      
   /* binds ports and set redirect for ssl wrapper */
   if (!GBL_OPTIONS->read && !GBL_OPTIONS->unoffensive && !GBL_OPTIONS->only_mitm && GBL_SNIFF->type == SM_UNIFIED)
      ssl_wrap_init();
   
   /* 
    * drop root privileges 
    * we have alread opened the sockets with high privileges
    * we don't need any more root privs.
    */
   drop_privs();

/***** !! NO PRIVS AFTER THIS POINT !! *****/

   /* load all the plugins */
   plugin_load_all();

   /* print how many dissectors were loaded */
   conf_dissectors();
   
   /* load the mac-fingerprints */
   manuf_init();

   /* load the tcp-fingerprints */
   fingerprint_init();
   
   /* load the services names */
   services_init();
   
   /* load http known fileds for user/pass */
   http_fields_init();

   /* set the encoding for the UTF-8 visualization */
   set_utf8_encoding(GBL_CONF->utf8_encoding);
  
   /* print all the buffered messages */
   if (GBL_UI->type == UI_TEXT)
      USER_MSG("\n");
   
   ui_msg_flush(MSG_ALL);

/**** INITIALIZATION PHASE TERMINATED ****/
   
   /* 
    * we are interested only in the mitm attack i
    * if entered, this function will not return...
    */
   if (GBL_OPTIONS->only_mitm)
      only_mitm();
   
   /* create the dispatcher thread */
   ec_thread_new("top_half", "dispatching module", &top_half, NULL);

   /* this thread becomes the UI then displays it */
   ec_thread_register(EC_PTHREAD_SELF, GBL_PROGRAM, "the user interface");
   ui_start();

/******************************************** 
 * reached only when the UI is shutted down 
 ********************************************/

   /* flush the exit message */
   ui_msg_flush(MSG_ALL);
   
   /* stop the mitm attack */
   mitm_stop();

   /* terminate the sniffing engine */
   EXECUTE(GBL_SNIFF->cleanup);
   
   /* kill all the running threads but the current */
   ec_thread_kill_all();
  
   /* clean up the UI */
   ui_cleanup();

   return 0;
}
Пример #16
0
Error AudioDriverCoreAudio::init() {
	mutex = Mutex::create();

	AudioComponentDescription desc;
	zeromem(&desc, sizeof(desc));
	desc.componentType = kAudioUnitType_Output;
#ifdef OSX_ENABLED
	desc.componentSubType = kAudioUnitSubType_HALOutput;
#else
	desc.componentSubType = kAudioUnitSubType_RemoteIO;
#endif
	desc.componentManufacturer = kAudioUnitManufacturer_Apple;

	AudioComponent comp = AudioComponentFindNext(NULL, &desc);
	ERR_FAIL_COND_V(comp == NULL, FAILED);

	OSStatus result = AudioComponentInstanceNew(comp, &audio_unit);
	ERR_FAIL_COND_V(result != noErr, FAILED);

#ifdef OSX_ENABLED
	AudioObjectPropertyAddress prop;
	prop.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
	prop.mScope = kAudioObjectPropertyScopeGlobal;
	prop.mElement = kAudioObjectPropertyElementMaster;

	result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop, &output_device_address_cb, this);
	ERR_FAIL_COND_V(result != noErr, FAILED);
#endif

	AudioStreamBasicDescription strdesc;

	zeromem(&strdesc, sizeof(strdesc));
	UInt32 size = sizeof(strdesc);
	result = AudioUnitGetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kOutputBus, &strdesc, &size);
	ERR_FAIL_COND_V(result != noErr, FAILED);

	switch (strdesc.mChannelsPerFrame) {
		case 2: // Stereo
		case 4: // Surround 3.1
		case 6: // Surround 5.1
		case 8: // Surround 7.1
			channels = strdesc.mChannelsPerFrame;
			break;

		default:
			// Unknown number of channels, default to stereo
			channels = 2;
			break;
	}

	mix_rate = GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE);

	zeromem(&strdesc, sizeof(strdesc));
	strdesc.mFormatID = kAudioFormatLinearPCM;
	strdesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
	strdesc.mChannelsPerFrame = channels;
	strdesc.mSampleRate = mix_rate;
	strdesc.mFramesPerPacket = 1;
	strdesc.mBitsPerChannel = 16;
	strdesc.mBytesPerFrame = strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8;
	strdesc.mBytesPerPacket = strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;

	result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &strdesc, sizeof(strdesc));
	ERR_FAIL_COND_V(result != noErr, FAILED);

	int latency = GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
	// Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
	buffer_frames = closest_power_of_2(latency * mix_rate / 1000);

#ifdef OSX_ENABLED
	result = AudioUnitSetProperty(audio_unit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, kOutputBus, &buffer_frames, sizeof(UInt32));
	ERR_FAIL_COND_V(result != noErr, FAILED);
#endif

	unsigned int buffer_size = buffer_frames * channels;
	samples_in.resize(buffer_size);
	input_buf.resize(buffer_size);
	input_buffer.resize(buffer_size * 8);
	input_position = 0;
	input_size = 0;

	print_verbose("CoreAudio: detected " + itos(channels) + " channels");
	print_verbose("CoreAudio: audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");

	AURenderCallbackStruct callback;
	zeromem(&callback, sizeof(AURenderCallbackStruct));
	callback.inputProc = &AudioDriverCoreAudio::output_callback;
	callback.inputProcRefCon = this;
	result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callback, sizeof(callback));
	ERR_FAIL_COND_V(result != noErr, FAILED);

	result = AudioUnitInitialize(audio_unit);
	ERR_FAIL_COND_V(result != noErr, FAILED);

	return capture_init();
}