From e9fa5c25f933c2ec70948506945a1714567631d1 Mon Sep 17 00:00:00 2001 From: boB Rudis Date: Sun, 29 Apr 2018 14:04:59 -0400 Subject: [PATCH] airport scanning --- .gitignore | 1 + NAMESPACE | 2 ++ R/airport-scan.R | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ R/mactheknife-package.R | 2 +- README.Rmd | 8 +++++++ README.md | 21 +++++++++++++++++ man/airport_scan.Rd | 17 ++++++++++++++ 7 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 R/airport-scan.R create mode 100644 man/airport_scan.Rd diff --git a/.gitignore b/.gitignore index cce1f17..769dae4 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ src/*.o src/*.so src/*.dll +README_cache \ No newline at end of file diff --git a/NAMESPACE b/NAMESPACE index d6ff8b9..c2098cb 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,5 +1,6 @@ # Generated by roxygen2: do not edit by hand +export(airport_scan) export(kernel_state) export(read_dsstore) export(software_update_history) @@ -11,5 +12,6 @@ import(xml2) importFrom(anytime,anytime) importFrom(purrr,"%>%") importFrom(purrr,flatten_chr) +importFrom(purrr,map_chr) importFrom(purrr,map_df) importFrom(purrr,set_names) diff --git a/R/airport-scan.R b/R/airport-scan.R new file mode 100644 index 0000000..8dd7182 --- /dev/null +++ b/R/airport-scan.R @@ -0,0 +1,60 @@ +#' Scan for available wireless network (requires Wi-Fi enabled Mac) +#' +#' @md +#' @param .quiet if `TRUE` then no progress messages will be displayed +#' @note that we have to use the characater output since the XML output is broken on Sierra. +#' @export +airport_scan <- function(.quiet=FALSE) { + + message("Scanning for available wireless networks...") + + sys::exec_internal( + "/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport", + "-s" + ) -> res + + if (length(res$stdout) == 0) { + stop('Error scanning for networks Are you running on a Wi-Fi-enables macOS system?', call.=FALSE) + } + + out <- rawToChar(res$stdout) + out <- strsplit(out, "[\r\n]+")[[1]] + out <- gsub("[\r\n]", "", out) + + rl <- rle(strsplit(gsub("[[A-Z]", "X", out[1]), "")[[1]]) + + ssid_len <- sum(rl$lengths[1:3]) + bssid_len <- sum(rl$lengths[4:5]) + rssi_len <- sum(rl$lengths[6:7]) + channel_len <- sum(rl$lengths[8:9]) + ht_len <- sum(rl$lengths[10:11]) + cc_len <- sum(rl$lengths[12:13]) + security_start <- ssid_len + bssid_len + rssi_len + channel_len + ht_len + cc_len + 1 + + saf <- default.stringsAsFactors() + on.exit(options(stringsAsFactors = saf)) + options(stringsAsFactors = FALSE) + + con <- textConnection(paste0(out[2:length(out)], collaspe="\n")) + read.fwf( + file = con, + widths = c(ssid_len, bssid_len, rssi_len, channel_len, ht_len, cc_len), + stringsAsFactors = FALSE + ) -> xdf + close(con) + + xdf <- xdf[complete.cases(xdf),] + xdf[] <- lapply(xdf, trimws) + xdf <- type.convert(xdf, as.is=TRUE) + + xdf$security <- + purrr::map_chr(out[2:length(out)], ~{ + substr(.x, security_start, nchar(.x)) + }) %>% trimws() + + colnames(xdf) <- c("ssid", "bssid", "rssi", "channel", "ht", "cc", "security") + + class(xdf) <- c("tbl_df", "tbl", "data.frame") + xdf + +} \ No newline at end of file diff --git a/R/mactheknife-package.R b/R/mactheknife-package.R index 5514e86..eb20d83 100644 --- a/R/mactheknife-package.R +++ b/R/mactheknife-package.R @@ -7,6 +7,6 @@ #' @docType package #' @author Bob Rudis (bob@@rud.is) #' @import reticulate sys xml2 -#' @importFrom purrr map_df %>% flatten_chr set_names +#' @importFrom purrr map_df %>% flatten_chr set_names map_chr #' @importFrom anytime anytime NULL diff --git a/README.Rmd b/README.Rmd index e15b15b..820b223 100644 --- a/README.Rmd +++ b/README.Rmd @@ -16,6 +16,7 @@ A set of tools/methods and data that are geared towards the 'macOS' ecosystem. ## What's Inside The Tin +- `airport_scan`: Scan for available wireless network (requires Wi-Fi enabled Mac) - `kernel_state`: Retrieve kernel state information - `read_dsstore`: Read a '.DS_Store' from a file/URL - `software_update_history`: Retrieve Software Update history @@ -95,3 +96,10 @@ software_update_history() ```{r} sw_vers() ``` + +### Airport scan + +```{r airport, cache=TRUE} +airport_scan() +``` + diff --git a/README.md b/README.md index c5f87ab..7ec8805 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ ecosystem. ## What’s Inside The Tin + - `airport_scan`: Scan for available wireless network (requires Wi-Fi + enabled Mac) - `kernel_state`: Retrieve kernel state information - `read_dsstore`: Read a ‘.DS\_Store’ from a file/URL - `software_update_history`: Retrieve Software Update history @@ -154,3 +156,22 @@ sw_vers() ## ProductName ProductVersion BuildVersion ## ## 1 Mac OS X 10.12.6 16G1405 + +### Airport scan + +``` r +airport_scan() +``` + + ## Scanning for available wireless networks... + + ## # A tibble: 7 x 7 + ## ssid bssid rssi channel ht cc security + ## * + ## 1 RDN-5G 46:d9:e7:b3:80:47 -66 11 Y -- WPA2(PSK,FT-PSK/AES/AES) + ## 2 RDN-100 56:d9:e7:b3:80:47 -72 11 Y -- WPA2(PSK,FT-PSK/AES/AES) + ## 3 xfinitywifi 6e:e3:0e:49:32:3d -91 6 Y US NONE + ## 4 shortcircut21 5c:e3:0e:49:32:3d -91 6 Y US WPA(PSK/AES,TKIP/TKIP) WPA2(PSK/AES,TKIP/TKIP) + ## 5 H20man-guest c2:56:27:62:a7:33 -87 1,+1 Y -- NONE + ## 6 RDN-5G 46:d9:e7:7b:9e:25 -51 1 Y -- WPA2(PSK,FT-PSK/AES/AES) + ## 7 RDN-100 56:d9:e7:7b:9e:25 -52 1 Y -- WPA2(PSK,FT-PSK/AES/AES) diff --git a/man/airport_scan.Rd b/man/airport_scan.Rd new file mode 100644 index 0000000..370d368 --- /dev/null +++ b/man/airport_scan.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/airport-scan.R +\name{airport_scan} +\alias{airport_scan} +\title{Scan for available wireless network (requires Wi-Fi enabled Mac)} +\usage{ +airport_scan(.quiet = FALSE) +} +\arguments{ +\item{.quiet}{if \code{TRUE} then no progress messages will be displayed} +} +\description{ +Scan for available wireless network (requires Wi-Fi enabled Mac) +} +\note{ +that we have to use the characater output since the XML output is broken on Sierra. +}