boB Rudis
6 years ago
19 changed files with 710 additions and 10 deletions
@ -1,4 +1,10 @@ |
|||
# Generated by roxygen2: do not edit by hand |
|||
|
|||
import(httr) |
|||
export("%>%") |
|||
export(install_zdns) |
|||
export(refresh_publc_nameservers_list) |
|||
export(zdns_exec) |
|||
export(zdns_help) |
|||
export(zdns_query) |
|||
importFrom(jsonlite,fromJSON) |
|||
importFrom(magrittr,"%>%") |
|||
|
@ -0,0 +1,18 @@ |
|||
#' Helper to try to get zdns installed |
|||
#' @export |
|||
install_zdns <- function() { |
|||
|
|||
res <- Sys.which("go") |
|||
if (res == "") { |
|||
packageStartupMessage( |
|||
"Go (golang) not found. Please install Go (https://golang.org/dl/) for ", |
|||
"your platform and try reloading the package again." |
|||
) |
|||
} else { |
|||
message( |
|||
"Attempting to install Go (golang). Please monitor the output for any ", |
|||
"errors that might occur during installation.") |
|||
res <- system2("go", c("get", "github.com/zmap/zdns/zdns"), stdout="") |
|||
} |
|||
|
|||
} |
@ -0,0 +1,8 @@ |
|||
#' Refresh the list of valid public nameservers |
|||
#' |
|||
#' @export |
|||
refresh_publc_nameservers_list <- function() { |
|||
if (!dir.exists(path.expand("~/.zdnsr"))) dir.create(path.expand("~/.zdnsr")) |
|||
xdf <- read.csv("https://public-dns.info/nameservers.csv", stringsAsFactors=FALSE) |
|||
saveRDS(xdf, file.path(path.expand("~/.zdnsr"), "public-nameservers.rds")) |
|||
} |
@ -0,0 +1,16 @@ |
|||
# NOTE!!! |
|||
# This requires map_lgl() which requries map() |
|||
|
|||
is_empty <- function(x) length(x) == 0 |
|||
|
|||
keep <- function(.x, .p, ...) { |
|||
.x[map_lgl(.x, .p, ...)] |
|||
} |
|||
|
|||
discard <- function(.x, .p, ...) { |
|||
.x[!map_lgl(.x, .p, ...)] |
|||
} |
|||
|
|||
compact <- function(.x, .p=identity) { |
|||
discard(.x, function(x) is_empty(.p(x))) |
|||
} |
@ -0,0 +1,320 @@ |
|||
# NOTE: At the bottom of this source file show the equivalents to purrr mappers |
|||
# |
|||
# NOTE these aren't 100% equivalent to the purrr mappers but cover very common use-cases |
|||
# |
|||
# NOTE formula function (e.g. ~{}) are 100% supported |
|||
# |
|||
# NOTE: THESE DO NOT SUPPORT list EXTRACTORS |
|||
|
|||
set_names <- function(object = nm, nm) { |
|||
names(object) <- nm |
|||
object |
|||
} |
|||
|
|||
map <- function(.x, .f, ..., .default) { |
|||
|
|||
default_exists <- !missing(.default) |
|||
|
|||
if (inherits(.f, "formula")) { |
|||
.body <- dimnames(attr(terms(.f), "factors"))[[1]] |
|||
.f <- function(.x, . = .x) {} |
|||
body(.f) <- as.expression(parse(text=.body)) |
|||
} |
|||
|
|||
nm <- names(.x) |
|||
|
|||
if (inherits(.f, "function")) { |
|||
|
|||
lapply(.x, function(x) { |
|||
res <- .f(x, ...) |
|||
if ((length(res) == 0) & default_exists) res <- .default |
|||
res |
|||
}) -> out |
|||
|
|||
} else if (is.numeric(.f) | is.character(.f)) { |
|||
|
|||
lapply(.x, function(x) { |
|||
res <- try(x[[.f]], silent = TRUE) |
|||
if (inherits(res, "try-error")) res <- NULL |
|||
if ((length(res) == 0) & default_exists) res <- .default |
|||
res |
|||
}) -> out |
|||
|
|||
} |
|||
|
|||
if (length(nm) > 0) out <- set_names(out, nm) |
|||
|
|||
out |
|||
|
|||
} |
|||
|
|||
map2 <- function(.x, .y, .f, ..., .default) { |
|||
|
|||
default_exists <- !missing(.default) |
|||
|
|||
if (inherits(.f, "formula")) { |
|||
.body <- dimnames(attr(terms(.f), "factors"))[[1]] |
|||
.f <- function(.x, .y, . = .x) {} |
|||
body(.f) <- as.expression(parse(text=.body)) |
|||
} |
|||
|
|||
if (inherits(.f, "function")) { |
|||
mapply( |
|||
function(x, ...) { |
|||
res <- .f(x, ...) |
|||
if ((length(res) == 0) & default_exists) res <- .default |
|||
res |
|||
}, |
|||
.x, .y, |
|||
..., |
|||
SIMPLIFY=FALSE, USE.NAMES=FALSE |
|||
) |
|||
} |
|||
|
|||
} |
|||
|
|||
map_chr <- function(.x, .f, ...) { |
|||
nm <- names(.x) |
|||
out <- as.character((map(.x, .f, ..., .default = .default))) |
|||
if (length(nm) > 0) set_names(out, nm) else out |
|||
} |
|||
|
|||
map2_chr <- function(.x, .y, .f, ...) { |
|||
as.character(unlist(map2(.x, .y, .f, ..., .default = .default))) |
|||
} |
|||
|
|||
map_lgl <- function(.x, .f, ...) { |
|||
nm <- names(.x) |
|||
out <- as.logical(unlist(map(.x, .f, ..., .default = .default))) |
|||
if (length(nm) > 0) set_names(out, nm) else out |
|||
} |
|||
|
|||
map2_lgl <- function(.x, .y, .f, ...) { |
|||
as.logical(unlist(map2(.x, .y, .f, ..., .default = .default))) |
|||
} |
|||
|
|||
map_dbl <- function(.x, .f, ...) { |
|||
nm <- names(.x) |
|||
out <- as.double(unlist(map(.x, .f, ..., .default = .default))) |
|||
if (length(nm) > 0) set_names(out, nm) else out |
|||
} |
|||
|
|||
map2_dbl <- function(.x, .y, .f, ...) { |
|||
as.double(unlist(map2(.x, .y, .f, ..., .default = .default))) |
|||
} |
|||
|
|||
map_int <- function(.x, .f, ..., .default) { |
|||
nm <- names(.x) |
|||
out <- as.integer(unlist(map(.x, .f, ..., .default = .default))) |
|||
if (length(nm) > 0) set_names(out, nm) else out |
|||
} |
|||
|
|||
map2_int <- function(.x, .y, .f, ...) { |
|||
as.integer(unlist(map2(.x, .y, .f, ..., .default = .default))) |
|||
} |
|||
|
|||
|
|||
map_df <- function(.x, .f, ..., .id=NULL) { |
|||
|
|||
res <- map(.x, .f, ...) |
|||
out <- bind_rows(res, .id=.id) |
|||
out |
|||
|
|||
} |
|||
|
|||
map_dfr <- map_df |
|||
|
|||
map_dfc <- function(.x, .f, ...) { |
|||
|
|||
res <- map(.x, .f, ...) |
|||
out <- bind_cols(res) |
|||
out |
|||
|
|||
} |
|||
|
|||
map2_df <- function(.x, .y, .f, ..., .id=NULL) { |
|||
|
|||
res <- map2(.x, .y, .f, ...) |
|||
out <- bind_rows(res, .id = .id) |
|||
out |
|||
|
|||
} |
|||
|
|||
|
|||
map2_dfc <- function(.x, .y, .f, ...) { |
|||
|
|||
res <- map2(.x, .y, .f, ...) |
|||
out <- bind_cols(res) |
|||
out |
|||
|
|||
} |
|||
|
|||
# this has limitations and is more like 75% of dplyr::bind_rows() |
|||
# this is also orders of magnitude slower than dplyr::bind_rows() |
|||
bind_rows <- function(..., .id = NULL) { |
|||
|
|||
res <- list(...) |
|||
|
|||
if (length(res) == 1) res <- res[[1]] |
|||
|
|||
cols <- unique(unlist(lapply(res, names), use.names = FALSE)) |
|||
|
|||
if (!is.null(.id)) { |
|||
inthere <- cols[.id %in% cols] |
|||
if (length(inthere) > 0) { |
|||
.id <- make.unique(c(inthere, .id))[2] |
|||
} |
|||
} |
|||
|
|||
id_vals <- if (is.null(names(res))) 1:length(res) else names(res) |
|||
|
|||
saf <- default.stringsAsFactors() |
|||
options(stringsAsFactors = FALSE) |
|||
on.exit(options(stringsAsFactors = saf)) |
|||
|
|||
idx <- 1 |
|||
do.call( |
|||
rbind.data.frame, |
|||
lapply(res, function(.x) { |
|||
x_names <- names(.x) |
|||
moar_names <- setdiff(cols, x_names) |
|||
if (length(moar_names) > 0) { |
|||
for (i in 1:length(moar_names)) { |
|||
.x[[moar_names[i]]] <- rep(NA, length(.x[[1]])) |
|||
} |
|||
} |
|||
if (!is.null(.id)) { |
|||
.x[[.id]] <- id_vals[idx] |
|||
idx <<- idx + 1 |
|||
} |
|||
.x |
|||
}) |
|||
) -> out |
|||
|
|||
rownames(out) <- NULL |
|||
|
|||
class(out) <- c("tbl_df", "tbl", "data.frame") |
|||
|
|||
out |
|||
|
|||
} |
|||
|
|||
bind_cols <- function(...) { |
|||
|
|||
res <- list(...) |
|||
|
|||
row_mismatch <- lapply(res, nrow) != nrow(res[[1]]) |
|||
|
|||
if (any(row_mismatch)) { |
|||
first_mismatch_pos <- which(row_mismatch)[1] |
|||
stop(paste0("Argument ", first_mismatch_pos, |
|||
" must be length ", nrow(res[[1]]), |
|||
", not ", nrow(res[[first_mismatch_pos]]))) |
|||
} |
|||
|
|||
if (length(res) == 1) res <- res[[1]] |
|||
|
|||
col_names <- unlist(lapply(res, names), use.names = FALSE) |
|||
col_names <- make.unique(col_names, sep = "") |
|||
|
|||
saf <- default.stringsAsFactors() |
|||
options(stringsAsFactors = FALSE) |
|||
on.exit(options(stringsAsFactors = saf)) |
|||
|
|||
out <- do.call(cbind.data.frame, res) |
|||
|
|||
names(out) <- col_names |
|||
rownames(out) <- NULL |
|||
|
|||
class(out) <- c("tbl_df", "tbl", "data.frame") |
|||
|
|||
out |
|||
|
|||
} |
|||
|
|||
|
|||
# set.seed(1) |
|||
# 1:10 %>% |
|||
# map(rnorm, n = 10) %>% |
|||
# map_dbl(mean) |
|||
# |
|||
# set.seed(1) |
|||
# 1:10 %>% |
|||
# purrr::map(rnorm, n = 10) %>% |
|||
# purrr::map_dbl(mean) |
|||
# |
|||
# |
|||
# # Or use an anonymous function |
|||
# set.seed(1) |
|||
# 1:10 %>% |
|||
# map(function(x) rnorm(10, x)) |
|||
# |
|||
# set.seed(1) |
|||
# 1:10 %>% |
|||
# purrr::map(function(x) rnorm(10, x)) |
|||
# |
|||
# # Or a formula |
|||
# set.seed(1) |
|||
# 1:10 %>% |
|||
# map(~ rnorm(10, .x)) |
|||
# |
|||
# set.seed(1) |
|||
# 1:10 %>% |
|||
# purrr::map(~ rnorm(10, .x)) |
|||
# |
|||
# # Extract by name or position |
|||
# # .default specifies value for elements that are missing or NULL |
|||
# l1 <- list(list(a = 1L), list(a = NULL, b = 2L), list(b = 3L)) |
|||
# l1 %>% map("a", .default = "???") |
|||
# l1 %>% purrr::map("a", .default = "???") |
|||
# |
|||
# l1 %>% map_int("b", .default = NA) |
|||
# l1 %>% purrr::map_int("b", .default = NA) |
|||
# |
|||
# l1 %>% map_int(2, .default = NA) |
|||
# l1 %>% purrr::map_int(2, .default = NA) |
|||
# |
|||
# # Supply multiple values to index deeply into a list |
|||
# l2 <- list( |
|||
# list(num = 1:3, letters[1:3]), |
|||
# list(num = 101:103, letters[4:6]), |
|||
# list() |
|||
# ) |
|||
# l2 %>% map(c(2, 2)) |
|||
# l2 %>% purrr::map(c(2, 2)) |
|||
# |
|||
# |
|||
# # A more realistic example: split a data frame into pieces, fit a |
|||
# # model to each piece, summarise and extract R^2 |
|||
# mtcars %>% |
|||
# split(.$cyl) %>% |
|||
# map(~ lm(mpg ~ wt, data = .x)) %>% |
|||
# map(summary) %>% |
|||
# map_dbl("r.squared") |
|||
# |
|||
# mtcars %>% |
|||
# split(.$cyl) %>% |
|||
# purrr::map(~ lm(mpg ~ wt, data = .x)) %>% |
|||
# purrr::map(summary) %>% |
|||
# purrr::map_dbl("r.squared") |
|||
# |
|||
# |
|||
# # Use map_lgl(), map_dbl(), etc to reduce to a vector. |
|||
# # * list |
|||
# mtcars %>% map(sum) |
|||
# mtcars %>% purrr::map(sum) |
|||
# # * vector |
|||
# mtcars %>% map_dbl(sum) |
|||
# mtcars %>% purrr::map_dbl(sum) |
|||
# |
|||
# # If each element of the output is a data frame, use |
|||
# # map_dfr to row-bind them together: |
|||
# mtcars %>% |
|||
# split(.$cyl) %>% |
|||
# map(~ lm(mpg ~ wt, data = .x)) %>% |
|||
# map_dfr(~ as.data.frame(t(as.matrix(coef(.))))) |
|||
# |
|||
# mtcars %>% |
|||
# split(.$cyl) %>% |
|||
# purrr::map(~ lm(mpg ~ wt, data = .x)) %>% |
|||
# purrr::map_dfr(~ as.data.frame(t(as.matrix(coef(.))))) |
@ -0,0 +1,11 @@ |
|||
#' Pipe operator |
|||
#' |
|||
#' See \code{magrittr::\link[magrittr]{\%>\%}} for details. |
|||
#' |
|||
#' @name %>% |
|||
#' @rdname pipe |
|||
#' @keywords internal |
|||
#' @export |
|||
#' @importFrom magrittr %>% |
|||
#' @usage lhs \%>\% rhs |
|||
NULL |
@ -0,0 +1,100 @@ |
|||
#' Bulk query using zdns |
|||
#' |
|||
#' Given an entity list and an output file, `zdns` will be executed and |
|||
#' JSON output stored in `output_file` and an optional `log` file |
|||
#' (if specified). |
|||
#' |
|||
#' @md |
|||
#' @param entities a character vector of entities to resolve |
|||
#' @param input_file if not `NULL`, overrides `entities` and this file |
|||
#' will be used as the entities source. It *must* be a plain text |
|||
#' file with one entity to resovle per-line. `path.expand()` will |
|||
#' be run on this value. |
|||
#' @param query_type anything `zdns` supports. Presently, one of `A`, `AAAA`, |
|||
#' `ANY`, `AXFR`, `CAA`, `CNAME`, `DMARC`, `MX`, `NS`, `PTR`, `TXT`, |
|||
#' `SOA`, or `SPF` (can be lower-case). Default is `A`. |
|||
#' @param output_file path + file to the JSON output. `path.expand()` will be run |
|||
#' on this value. |
|||
#' @param num_nameservers total number of nameservers to use. They will be randomly |
|||
#' selected from the cached list of valid, public nameservers. It is _highly_ |
|||
#' recommended that you refresh this list periodicaly (perhaps daily). |
|||
#' @param num_retries how many times should `zdns` retry query if timeout or |
|||
#' temporary failure? Defaults to `3`. |
|||
#' @param log if `TRUE` the JSON error log file will be automatically generated and |
|||
#' the location printed to the console. If a length 1 character vector, this |
|||
#' path + file will be used to save the JSON error log. If `FALSE` no error |
|||
#' log will be captured. |
|||
#' @param verbose a value between `1` and `5` indicating the verbosity level. Defaults |
|||
#' to `3`. Set this to `1` if you're working inside RStudio or other |
|||
#' environments that can't handle a great deal of console text since |
|||
#' the messages are placed on `stdout` when `log` equals `FALSE`. |
|||
#' @return value from the `system2()` call to `zdns` (invisibly) |
|||
#' @note if you specified `TRUE` for `log` then _you_ are responsible for |
|||
#' removing the auto-generated log file. |
|||
#' @export |
|||
zdns_query <- function(entities, input_file = NULL, query_type = "A", output_file, |
|||
num_nameservers = 3000L, num_retries = 3, |
|||
log = TRUE, verbose = 3) { |
|||
|
|||
# setup entities to lookup |
|||
|
|||
if (!is.null(input_file)) { |
|||
input_file <- path.expand(input_file) |
|||
if (!file.exists(input_file)) stop("input file not found", call.=FALSE) |
|||
} else { |
|||
tf <- tempfile(fileext=".txt") |
|||
on.exit(unlink(tf), add=TRUE) |
|||
writeLines(entities, tf) |
|||
input_file <- tf |
|||
} |
|||
|
|||
# make sure query type is legit |
|||
match.arg( |
|||
toupper(query_type), |
|||
c( |
|||
"A", "AAAA", "ANY", "AXFR", "CAA", "CNAME", "DMARC", |
|||
"MX", "NS", "PTR", "TXT", "SOA", "SPF" |
|||
) |
|||
) -> query_type |
|||
|
|||
# prep nameservers list |
|||
ns_df <- readRDS(file.path(path.expand("~/.zdnsr"), "public-nameservers.rds")) |
|||
ns_df <- ns_df[ns_df$reliability>0.75,] |
|||
ns_file <- tempfile(pattern = "resolvers", fileext = ".txt") |
|||
writeLines(sprintf("nameserver %s", ns_df[sample(nrow(ns_df), num_nameservers),]$ip), ns_file) |
|||
on.exit(unlink(ns_file), add=TRUE) |
|||
|
|||
# setup logging (if any) |
|||
logging <- FALSE |
|||
if (inherits(log, "character")) { |
|||
log_file <- log |
|||
logging <- TRUE |
|||
} else { |
|||
if (inherits(log, "logical")) { |
|||
if (log) { |
|||
log_file <- tempfile("zmap-error", fileext=".json") |
|||
logging <- TRUE |
|||
message("zmap error log will be stored in ", log_file) |
|||
} else { |
|||
message("Not logging errors.") |
|||
} |
|||
} else { |
|||
message("Not logging errors.") |
|||
} |
|||
} |
|||
|
|||
# prep args for call to zdns |
|||
zdns_args <- c( |
|||
query_type, |
|||
"-input-file", input_file, |
|||
"-conf-file", ns_file, |
|||
"-output-file", output_file, |
|||
"-retries", num_retries, |
|||
"-verbosity", verbose |
|||
) |
|||
|
|||
if (logging) zdns_args <- c(zdns_args, "-log-file", log_file) |
|||
|
|||
invisible(zdns_exec(zdns_args)) |
|||
|
|||
} |
@ -0,0 +1,23 @@ |
|||
#' Raw interface to zdns |
|||
#' |
|||
#' Pass in command-line arguments via `args`. Not a recommended function |
|||
#' unless you _really_ know what you're doing. Run `zdns_help()` |
|||
#' to see a list of options. |
|||
#' |
|||
#' @md |
|||
#' @export |
|||
zdns_exec <- function(args=c(), stdout="", stdin="") { |
|||
|
|||
zdns_bin <- Sys.which("zdns") |
|||
|
|||
res <- system2(zdns_bin, args=args, stdout=stdout, stdin=stdin) |
|||
|
|||
invisible(res) |
|||
|
|||
} |
|||
|
|||
#' @rdname zdns_exec |
|||
#' @export |
|||
zdns_help <- function(x) { |
|||
zdns_exec("--help") |
|||
} |
@ -1,12 +1,18 @@ |
|||
#' ... |
|||
#' |
|||
#' Perform Bulk 'DNS' Queries Using 'zdns' |
|||
#' |
|||
#' Provides wrapper/helper methods for executing 'zdns' |
|||
#' (<https://github.com/zmap/zdns>) bulk queries along with utility methods to |
|||
#' retrieve and cache 'Public DNS' (<http://public-dns.info/>) nameserver lists. |
|||
#' |
|||
#' - `zdns`: <https://github.com/zmap/zdns> |
|||
#' - `Public DNS Lists`: <http://public-dns.info/> |
|||
#' |
|||
#' - URL: <https://gitlab.com/hrbrmstr/zdnsr> |
|||
#' - BugReports: <https://gitlab.com/hrbrmstr/zdnsr/issues> |
|||
#' |
|||
#' |
|||
#' @md |
|||
#' @name zdnsr |
|||
#' @docType package |
|||
#' @author Bob Rudis (bob@@rud.is) |
|||
#' @import httr |
|||
#' @importFrom jsonlite fromJSON |
|||
NULL |
|||
|
@ -0,0 +1,26 @@ |
|||
.onLoad <- function(libname, pkgname) { |
|||
|
|||
if (!dir.exists(path.expand("~/.zdnsr"))) { |
|||
message("Bootstrapping public nameservers list...") |
|||
refresh_publc_nameservers_list() |
|||
} |
|||
|
|||
res <- Sys.which("go") |
|||
if (res == "") { |
|||
packageStartupMessage( |
|||
"Go (golang) not found. Please install Go (https://golang.org/dl/) for ", |
|||
"your platform and try reloading the package again." |
|||
) |
|||
} else { |
|||
|
|||
res <- Sys.which("zdns") |
|||
if (res == "") { |
|||
packageStartupMessage( |
|||
"zdns not found. Please go to https://github.com/zmap/zdns to find ", |
|||
"installation instructions or try running install_zdns()." |
|||
) |
|||
} |
|||
|
|||
} |
|||
|
|||
} |
@ -1,2 +1,42 @@ |
|||
|
|||
# zdnsr |
|||
|
|||
Perform Bulk ‘DNS’ Queries Using ‘zdns’ |
|||
|
|||
## Description |
|||
|
|||
Provides wrapper/helper methods for executing ‘zdns’ |
|||
(<https://github.com/zmap/zdns>) bulk queries along with utility methods |
|||
to retrieve and cache ‘Public DNS’ (<http://public-dns.info/>) |
|||
nameserver lists. |
|||
|
|||
- `zdns`: <https://github.com/zmap/zdns> |
|||
- `Public DNS Lists`: <http://public-dns.info/> |
|||
|
|||
## What’s Inside The Tin |
|||
|
|||
The following functions are implemented: |
|||
|
|||
- `install_zdns`: Helper to try to get `zdns` installed |
|||
- `refresh_publc_nameservers_list`: Refresh the list of valid public |
|||
nameservers |
|||
- `zdns_exec`: Raw interface to `zdns` |
|||
- `zdns_help`: Raw interface to `zdns` |
|||
- `zdns_query`: Bulk query using `zdns` |
|||
|
|||
## Installation |
|||
|
|||
``` r |
|||
devtools::install_github("hrbrmstr/zdnsr") |
|||
``` |
|||
|
|||
## Usage |
|||
|
|||
``` r |
|||
library(zdnsr) |
|||
|
|||
# current verison |
|||
packageVersion("zdnsr") |
|||
``` |
|||
|
|||
## [1] '0.1.0' |
|||
|
@ -0,0 +1,11 @@ |
|||
% Generated by roxygen2: do not edit by hand |
|||
% Please edit documentation in R/install-zdns.R |
|||
\name{install_zdns} |
|||
\alias{install_zdns} |
|||
\title{Helper to try to get zdns installed} |
|||
\usage{ |
|||
install_zdns() |
|||
} |
|||
\description{ |
|||
Helper to try to get zdns installed |
|||
} |
@ -0,0 +1,12 @@ |
|||
% Generated by roxygen2: do not edit by hand |
|||
% Please edit documentation in R/utils-pipe.R |
|||
\name{\%>\%} |
|||
\alias{\%>\%} |
|||
\title{Pipe operator} |
|||
\usage{ |
|||
lhs \%>\% rhs |
|||
} |
|||
\description{ |
|||
See \code{magrittr::\link[magrittr]{\%>\%}} for details. |
|||
} |
|||
\keyword{internal} |
@ -0,0 +1,11 @@ |
|||
% Generated by roxygen2: do not edit by hand |
|||
% Please edit documentation in R/ns-refresh.R |
|||
\name{refresh_publc_nameservers_list} |
|||
\alias{refresh_publc_nameservers_list} |
|||
\title{Refresh the list of valid public nameservers} |
|||
\usage{ |
|||
refresh_publc_nameservers_list() |
|||
} |
|||
\description{ |
|||
Refresh the list of valid public nameservers |
|||
} |
@ -0,0 +1,16 @@ |
|||
% Generated by roxygen2: do not edit by hand |
|||
% Please edit documentation in R/zdns-exec.R |
|||
\name{zdns_exec} |
|||
\alias{zdns_exec} |
|||
\alias{zdns_help} |
|||
\title{Raw interface to zdns} |
|||
\usage{ |
|||
zdns_exec(args = c(), stdout = "", stdin = "") |
|||
|
|||
zdns_help(x) |
|||
} |
|||
\description{ |
|||
Pass in command-line arguments via \code{args}. Not a recommended function |
|||
unless you \emph{really} know what you're doing. Run \code{zdns_help()} |
|||
to see a list of options. |
|||
} |
@ -0,0 +1,53 @@ |
|||
% Generated by roxygen2: do not edit by hand |
|||
% Please edit documentation in R/zdns-bulk-query.R |
|||
\name{zdns_query} |
|||
\alias{zdns_query} |
|||
\title{Bulk query using zdns} |
|||
\usage{ |
|||
zdns_query(entities, input_file = NULL, query_type = "A", output_file, |
|||
num_nameservers = 3000L, num_retries = 3, log = TRUE, verbose = 3) |
|||
} |
|||
\arguments{ |
|||
\item{entities}{a character vector of entities to resolve} |
|||
|
|||
\item{input_file}{if not \code{NULL}, overrides \code{entities} and this file |
|||
will be used as the entities source. It \emph{must} be a plain text |
|||
file with one entity to resovle per-line. \code{path.expand()} will |
|||
be run on this value.} |
|||
|
|||
\item{query_type}{anything \code{zdns} supports. Presently, one of \code{A}, \code{AAAA}, |
|||
\code{ANY}, \code{AXFR}, \code{CAA}, \code{CNAME}, \code{DMARC}, \code{MX}, \code{NS}, \code{PTR}, \code{TXT}, |
|||
\code{SOA}, or \code{SPF} (can be lower-case). Default is \code{A}.} |
|||
|
|||
\item{output_file}{path + file to the JSON output. \code{path.expand()} will be run |
|||
on this value.} |
|||
|
|||
\item{num_nameservers}{total number of nameservers to use. They will be randomly |
|||
selected from the cached list of valid, public nameservers. It is \emph{highly} |
|||
recommended that you refresh this list periodicaly (perhaps daily).} |
|||
|
|||
\item{num_retries}{how many times should \code{zdns} retry query if timeout or |
|||
temporary failure? Defaults to \code{3}.} |
|||
|
|||
\item{log}{if \code{TRUE} the JSON error log file will be automatically generated and |
|||
the location printed to the console. If a length 1 character vector, this |
|||
path + file will be used to save the JSON error log. If \code{FALSE} no error |
|||
log will be captured.} |
|||
|
|||
\item{verbose}{a value between \code{1} and \code{5} indicating the verbosity level. Defaults |
|||
to \code{3}. Set this to \code{1} if you're working inside RStudio or other |
|||
environments that can't handle a great deal of console text since |
|||
the messages are placed on \code{stdout} when \code{log} equals \code{FALSE}.} |
|||
} |
|||
\value{ |
|||
value from the \code{system2()} call to \code{zdns} (invisibly) |
|||
} |
|||
\description{ |
|||
Given an entity list and an output file, \code{zdns} will be executed and |
|||
JSON output stored in \code{output_file} and an optional \code{log} file |
|||
(if specified). |
|||
} |
|||
\note{ |
|||
if you specified \code{TRUE} for \code{log} then \emph{you} are responsible for |
|||
removing the auto-generated log file. |
|||
} |
Loading…
Reference in new issue