Ejemplo n.º 1
0
int
main(int argc, char * argv[])
{
    int			a_flag = 0;
    struct ether_addr	AP_mac;
    int			ch;
    boolean_t		disassociate = FALSE;
    const char *	if_name = NULL;
    boolean_t		has_wireless;
    const char *	key_str = NULL;
    const char *	network = NULL;
    int			scan_current_ssid = FALSE;
    struct sockaddr_dl	w;
    wireless_t		wref;
	
    while ((ch =  getopt(argc, argv, "adhHi:k:sx:")) != EOF) {
		switch ((char)ch) {
			case 'a':
				a_flag = 1;
				break;
			case 'h':
			case 'H':
				EAPLOG(LOG_ERR,
						"usage: wireless [ -i <interface> ] ( -d | -k | -x <ssid> | -s [ -a ])\n");
				exit(0);
				break;
			case 'x':		/* join network */
				network = optarg;
				break;
			case 'k':		/* set the wireless key */
				key_str = optarg;
				break;
			case 'd':
				disassociate = TRUE;
				break;
			case 'i':		/* specify the interface */
				if_name = optarg;
				break;
			case 's':
				scan_current_ssid = TRUE;
				break;
			default:
				break;
		}
    }
	
    if (if_name != NULL) {
		if (wireless_bind(if_name, &wref) == FALSE) {
			printf("interface '%s' is not present or not AirPort\n",
				   if_name);
			exit(1);
		}
    }
    else if ((if_name = wireless_first(&wref)) == NULL) {
		printf("no AirPort card\n");
		exit(0);
    }
    get_mac_address(if_name, &w);
    printf("AirPort: %s %s\n", if_name,
		   ether_ntoa((struct ether_addr *)(w.sdl_data + w.sdl_nlen)));
	
    if (wireless_ap_mac(wref, &AP_mac) == FALSE) {
		printf("Not associated\n");
    }
    else {
		CFStringRef	ssid;
		
		printf("Access Point: %s\n", ether_ntoa(&AP_mac));
		ssid = wireless_copy_ssid_string(wref);
		if (ssid != NULL) {
			printf("SSID: ");
			fflush(stdout);
			CFShow(ssid);
			fflush(stderr);
		}
		if (wireless_is_wpa_enterprise(wref) == TRUE) {
			printf("WPA Enterprise\n");
		}
		else {
			printf("Not WPA Enterprise\n");
		}
		if (disassociate) {
			wireless_disassociate(wref);
			goto done;
		}
		else if (scan_current_ssid) {
			if (a_flag) {
				if (wireless_async_scan_ssid(wref, ssid)) {
					CFRunLoopObserverContext	context
					= { 0, NULL, NULL, NULL, NULL };
					CFRunLoopObserverRef	observer;
					struct ssid_wref		ref;
					
					
					ref.ssid = ssid;
					ref.wref = wref;
					context.info = &ref;
					observer
					= CFRunLoopObserverCreate(NULL,
											  kCFRunLoopBeforeWaiting,
											  TRUE, 0, before_blocking,
											  &context);
					if (observer != NULL) {
						CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer,
											 kCFRunLoopDefaultMode);
					}
					else {
						EAPLOG(LOG_ERR, "start_initialization: "
								"CFRunLoopObserverCreate failed!");
					}
					CFRunLoopRun();
				}
				else {
					exit(1);
				}
			}
			else {
				wireless_scan_ssid(wref, ssid);
			}
		}
		my_CFRelease(&ssid);
    }
    if (key_str) {
		uint8_t	key[13];
		int	key_len;
		int	hex_len = strlen(key_str);
		
		if (hex_len & 0x1) {
			EAPLOG(LOG_ERR, "invalid key, odd number of hex bytes\n");
			exit(1);
		}
		key_len = hex_len / 2;
		
		switch (key_len) {
			case 5:
			case 13:
				hexstrtobin(key_str, hex_len, key, key_len);
				if (wireless_set_key(wref, 0, 0, key, key_len)
					== FALSE) {
					EAPLOG(LOG_ERR, "wireless_set_key failed\n");
				}
				break;
			default:
				EAPLOG(LOG_ERR,
						"invalid key length %d,"
						" must be 5 or 13 hex bytes\n", key_len);
				exit(1);
				break;
		}
    }
    else if (network != NULL) {
		CFDataRef	data;
		CFStringRef	ssid_str;
		
		data = CFDataCreateWithBytesNoCopy(NULL, (const UInt8 *)network,
										   strlen(network), kCFAllocatorNull);
		ssid_str = ssid_string_from_data(data);
		EAPLOG(LOG_ERR, "attempting to join network '%s'\n", network);
		if (wireless_join(wref, ssid_str) == FALSE) {
			EAPLOG(LOG_ERR, "wireless_join failed\n");
		}
    }
done:
    wireless_free(wref);
    exit(0);
    return (0);
}
Ejemplo n.º 2
0
/* Retrieve the wifi SAR limits data from VPD and decode it

For VPD: key,value pair is in this format
"wifi_sar"=[<WRDD><EWRD>][WGDS]

WIFI SAR data in CBFS file is expected in same format: [<WRDD><EWRD>][WGDS]

[<WRDD><EWRD>] = NUM_SAR_LIMITS * BYTES_PER_SAR_LIMIT bytes.
[WGDS]=[WGDS_VERSION][WGDS_DATA]

For [WGDS_VERSION] 0x00,
[WGDS_DATA] = [GROUP#0][GROUP#1][GROUP#2]

[GROUP#<i>] =
	[2.4Ghz – Max Allowed][2.4Ghz – Chain A Offset]
	[2.4Ghz – Chain B Offset][5Ghz – Max Allowed]
	[5Ghz – Chain A Offset][5Ghz – Chain B Offset]

[GROUP#0] is for FCC
[GROUP#1] is for Europe/Japan
[GROUP#2] is for ROW

*/
int get_wifi_sar_limits(struct wifi_sar_limits *sar_limits)
{
	const char *wifi_sar_limit_key = CROS_VPD_WIFI_SAR_NAME;
	/* vpd_gets() reads in one less than size characters from the VPD
	 * with a terminating null byte ('\0') stored as the last character into
	 * the buffer, thus the increasing by 1 for buffer_size. */
	const size_t buffer_size = (sizeof(struct wifi_sar_limits) /
					sizeof(uint8_t)) * 2 + 1;
	char wifi_sar_limit_str[buffer_size];
	uint8_t bin_buffer[sizeof(struct wifi_sar_limits)];
	size_t sar_cbfs_len, sar_expected_len, bin_buff_adjusted_size;

	/* keep it backward compatible. Some older platform are shipping
	   without GEO SAR and so older wifi_sar VPD key */

	sar_expected_len = buffer_size;
	bin_buff_adjusted_size = sizeof(struct wifi_sar_limits);

	if (!IS_ENABLED(CONFIG_GEO_SAR_ENABLE)) {
		sar_expected_len = buffer_size -
					sizeof(struct wifi_sar_delta_table) *
					sizeof(uint8_t) * 2;
		bin_buff_adjusted_size = sizeof(struct wifi_sar_limits) -
					 sizeof(struct wifi_sar_delta_table);
	}

	/* Try to read the SAR limit entry from VPD */
	if (!vpd_gets(wifi_sar_limit_key, wifi_sar_limit_str,
							 buffer_size, VPD_ANY)) {
		printk(BIOS_ERR, "Error: Could not locate '%s' in VPD.\n",
				wifi_sar_limit_key);

		if (!IS_ENABLED(CONFIG_WIFI_SAR_CBFS))
			return -1;

		printk(BIOS_DEBUG, "Checking CBFS for default SAR values\n");

		sar_cbfs_len = load_sar_file_from_cbfs(
					(void *) wifi_sar_limit_str,
						sar_expected_len);

		if (sar_cbfs_len != sar_expected_len) {
			printk(BIOS_ERR, "%s has bad len in CBFS\n",
					WIFI_SAR_CBFS_FILENAME);
			return -1;
		}
	} else {
		/* VPD key "wifi_sar" found. strlen is checked with addition of
		 * 1 as we have created buffer size 1 char larger for the reason
		 * mentioned at start of this function itself */
		if (strlen(wifi_sar_limit_str) + 1 != sar_expected_len) {
			printk(BIOS_ERR, "WIFI SAR key has bad len in VPD\n");
			return -1;
		}
	}

	/* Decode the heximal encoded string to binary values */
	if (hexstrtobin(wifi_sar_limit_str, bin_buffer, bin_buff_adjusted_size)
			< bin_buff_adjusted_size) {
		printk(BIOS_ERR, "Error: wifi_sar contains non-hex value!\n");
		return -1;
	}

	memset(sar_limits, 0, sizeof(*sar_limits));
	memcpy(sar_limits, bin_buffer, bin_buff_adjusted_size);
	return 0;
}