Browse Source

SRV, aliases, credit

master
boB Rudis 4 years ago
parent
commit
6a74e1eb02
No known key found for this signature in database GPG Key ID: 1D7529BE14E2BBA9
  1. 10
      DESCRIPTION
  2. 2
      NAMESPACE
  3. 8
      NEWS.md
  4. 8
      R/RcppExports.R
  5. 14
      R/discover.R
  6. 16
      R/query.R
  7. 52
      README.md
  8. 15
      man/bnjr_discover.Rd
  9. 13
      man/bnjr_query.Rd
  10. 18
      src/RcppExports.cpp
  11. 37
      src/bonjour-main.cpp
  12. 22
      src/mdns.h

10
DESCRIPTION

@ -1,11 +1,13 @@
Package: bonjour
Type: Package
Title: Discover and Query Multicast DNS (mDNS)/zeroconf Services
Version: 0.1.0
Date: 2020-04-29
Version: 0.2.0
Date: 2020-05-04
Authors@R: c(
person("Bob", "Rudis", email = "bob@rud.is", role = c("aut", "cre"),
comment = c(ORCID = "0000-0001-5670-2640"))
person("Bob", "Rudis", email = "bob@rud.is", role = c("aut", "cre"),
comment = c(ORCID = "0000-0001-5670-2640")),
person("Mattias", "Jansson", email = "mjansson@gmail.com", role = "aut",
comment = "https://github.com/mjansson/mdns")
)
Maintainer: Bob Rudis <bob@rud.is>
Description: Multicast DNS (mDNS) provides the ability to perform DNS-like

2
NAMESPACE

@ -4,6 +4,8 @@ export(bjr_discover)
export(bjr_query)
export(bnjr_discover)
export(bnjr_query)
export(mdns_discover)
export(mdns_query)
importFrom(Rcpp,sourceCpp)
importFrom(ndjson,flatten)
useDynLib(bonjour, .registration = TRUE)

8
NEWS.md

@ -1,2 +1,10 @@
0.2.0
* Added Credit to Mattias Jansson for the mdns C library
* Added in support for SRV records
* Added in support for IPv6 but use @ own risk for now
* Fixed document aliases for `bjr_` aliases
* Adeed `mdns_` aliases b/c I keep trying to use them
* Added return value docs
0.1.0
* Initial release

8
R/RcppExports.R

@ -1,11 +1,11 @@
# Generated by using Rcpp::compileAttributes() -> do not edit by hand
# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
int_bnjr_discover <- function(scan_time = 10L) {
.Call(`_bonjour_int_bnjr_discover`, scan_time)
int_bnjr_discover <- function(scan_time = 10L, proto = "ipv4") {
.Call(`_bonjour_int_bnjr_discover`, scan_time, proto)
}
int_bnjr_query <- function(q, scan_time = 5L) {
.Call(`_bonjour_int_bnjr_query`, q, scan_time)
int_bnjr_query <- function(q, scan_time = 5L, proto = "ipv4") {
.Call(`_bonjour_int_bnjr_query`, q, scan_time, proto)
}

14
R/discover.R

@ -2,10 +2,14 @@
#'
#' @param scan_time how long to scan for services; default is 10 and
#' should not really be that much lower in most networks.
#' @param proto "`ipv4`" or "`ipv6`"
#' @return data frame
#' @export
bnjr_discover <- function(scan_time = 10L) {
bnjr_discover <- function(scan_time = 10L, proto = c("ipv4", "ipv6")) {
res <- int_bnjr_discover(scan_time)
proto <- match.arg(tolower(trimws(proto[1])), c("ipv4", "ipv6"))
res <- int_bnjr_discover(scan_time, proto = proto)
res <- unlist(strsplit(res, "\n"))
ndjson::flatten(res, "tbl")
@ -13,4 +17,8 @@ bnjr_discover <- function(scan_time = 10L) {
#' @rdname bnjr_discover
#' @export
bjr_discover <- bnjr_discover
bjr_discover <- bnjr_discover
#' @rdname bnjr_discover
#' @export
mdns_discover <- bnjr_discover

16
R/query.R

@ -3,15 +3,23 @@
#' @param query service to look for
#' @param scan_time how long to scan for services; default is 10 and
#' should not really be that much lower in most networks.
#' @param proto "`ipv4`" or "`ipv6`"
#' @return data frame
#' @export
bnjr_query <- function(query, scan_time = 10L) {
bnjr_query <- function(query, scan_time = 10L, proto = c("ipv4", "ipv6")) {
res <- int_bnjr_query(query, scan_time)
proto <- match.arg(tolower(trimws(proto[1])), c("ipv4", "ipv6"))
res <- int_bnjr_query(query, scan_time, proto = proto)
res <- unlist(strsplit(res, "\n"))
ndjson::flatten(res, "tbl")
}
#' @rdname bnjr_discover
#' @rdname bnjr_query
#' @export
bjr_query <- bnjr_query
#' @rdname bnjr_query
#' @export
bjr_query <- bnjr_query
mdns_query <- bnjr_query

52
README.md

@ -61,25 +61,25 @@ library(tidyverse)
# current version
packageVersion("bonjour")
## [1] '0.1.0'
## [1] '0.2.0'
```
``` r
bnjr_discover()
## # A tibble: 49 x 7
## entry_type from length name rclass ttl type
## <chr> <chr> <dbl> <chr> <dbl> <dbl> <chr>
## 1 answer 10.1.10.59:5353 12 _ssh._tcp.local. 1 10 PTR
## 2 answer 10.1.10.59:5353 12 _sftp-ssh._tcp.local. 1 10 PTR
## 3 answer 10.1.10.59:5353 8 _eppc._tcp.local. 1 10 PTR
## 4 answer 10.1.10.59:5353 7 _rfb._tcp.local. 1 10 PTR
## 5 answer 10.1.10.59:5353 7 _smb._tcp.local. 1 10 PTR
## 6 answer 10.1.10.59:5353 17 _net-assistant._udp.local. 1 10 PTR
## 7 answer 10.1.10.59:5353 18 _companion-link._tcp.local. 1 10 PTR
## 8 answer 10.1.10.192:5353 12 _smb._tcp.local. 1 10 PTR
## 9 answer 10.1.10.20:5353 14 _adisk._tcp.local. 1 10 PTR
## 10 answer 10.1.10.20:5353 7 _ssh._tcp.local. 1 10 PTR
## # … with 39 more rows
## # A tibble: 58 x 7
## entry_type from length name rclass ttl type
## <chr> <chr> <dbl> <chr> <dbl> <dbl> <chr>
## 1 answer 10.1.10.20:5353 14 _adisk._tcp.local. 1 10 PTR
## 2 answer 10.1.10.20:5353 7 _ssh._tcp.local. 1 10 PTR
## 3 answer 10.1.10.20:5353 12 _sftp-ssh._tcp.local. 1 10 PTR
## 4 answer 10.1.10.20:5353 8 _eppc._tcp.local. 1 10 PTR
## 5 answer 10.1.10.20:5353 7 _rfb._tcp.local. 1 10 PTR
## 6 answer 10.1.10.20:5353 7 _smb._tcp.local. 1 10 PTR
## 7 answer 10.1.10.20:5353 7 _nfs._tcp.local. 1 10 PTR
## 8 answer 10.1.10.20:5353 17 _net-assistant._udp.local. 1 10 PTR
## 9 answer 10.1.10.20:5353 18 _companion-link._tcp.local. 1 10 PTR
## 10 answer 10.1.10.20:5353 14 _1password4._tcp.local. 1 10 PTR
## # … with 48 more rows
```
``` r
@ -89,13 +89,13 @@ bnjr_query("_ssh._tcp.local.") %>%
## # A tibble: 9 x 1
## addr
## <chr>
## 1 fe80::1410:647:b4c1:df43
## 2 2603:3005:146a:8000:1459:ebc3:42dc:5ae2
## 3 fe80::1864:a1e2:98b:44d0
## 4 2603:3005:146a:8000:189b:85a2:64f5:598f
## 5 fe80::18f8:a74b:6a0d:9175
## 6 2603:3005:146a:8000:c98:42f7:9943:4b73
## 7 2603:3005:146a:8000:6972:7ff9:9594:5467
## 1 fe80::1864:a1e2:98b:44d0
## 2 2603:3005:146a:8000:189b:85a2:64f5:598f
## 3 2603:3005:146a:8000:c98:42f7:9943:4b73
## 4 fe80::18f8:a74b:6a0d:9175
## 5 fe80::c24:9c04:594:5f28
## 6 2603:3005:146a:8000:1459:ebc3:42dc:5ae2
## 7 2603:3005:146a:8000:14b9:cc5f:f330:90f8
## 8 fe80::1041:d138:41f8:efd5
## 9 2603:3005:146a:8000:c95:dcb9:cc3a:d030
```
@ -104,10 +104,10 @@ bnjr_query("_ssh._tcp.local.") %>%
| Lang | \# Files | (%) | LoC | (%) | Blank lines | (%) | \# Lines | (%) |
| :----------- | -------: | ---: | --: | ---: | ----------: | ---: | -------: | ---: |
| C/C++ Header | 1 | 0.11 | 936 | 0.76 | 154 | 0.55 | 87 | 0.47 |
| C++ | 2 | 0.22 | 255 | 0.21 | 97 | 0.35 | 28 | 0.15 |
| R | 5 | 0.56 | 22 | 0.02 | 11 | 0.04 | 38 | 0.21 |
| Rmd | 1 | 0.11 | 13 | 0.01 | 17 | 0.06 | 32 | 0.17 |
| C/C++ Header | 1 | 0.11 | 932 | 0.76 | 154 | 0.54 | 91 | 0.46 |
| C++ | 2 | 0.22 | 261 | 0.21 | 101 | 0.35 | 31 | 0.16 |
| R | 5 | 0.56 | 26 | 0.02 | 15 | 0.05 | 46 | 0.23 |
| Rmd | 1 | 0.11 | 13 | 0.01 | 17 | 0.06 | 32 | 0.16 |
## Code of Conduct

15
man/bnjr_discover.Rd

@ -1,20 +1,25 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/discover.R, R/query.R
% Please edit documentation in R/discover.R
\name{bnjr_discover}
\alias{bnjr_discover}
\alias{bjr_discover}
\alias{bjr_query}
\alias{mdns_discover}
\title{Browse available services}
\usage{
bnjr_discover(scan_time = 10L)
bnjr_discover(scan_time = 10L, proto = c("ipv4", "ipv6"))
bjr_discover(scan_time = 10L)
bjr_discover(scan_time = 10L, proto = c("ipv4", "ipv6"))
bjr_query(query, scan_time = 10L)
mdns_discover(scan_time = 10L, proto = c("ipv4", "ipv6"))
}
\arguments{
\item{scan_time}{how long to scan for services; default is 10 and
should not really be that much lower in most networks.}
\item{proto}{"\code{ipv4}" or "\code{ipv6}"}
}
\value{
data frame
}
\description{
Browse available services

13
man/bnjr_query.Rd

@ -2,15 +2,26 @@
% Please edit documentation in R/query.R
\name{bnjr_query}
\alias{bnjr_query}
\alias{bjr_query}
\alias{mdns_query}
\title{Look for a particular service}
\usage{
bnjr_query(query, scan_time = 10L)
bnjr_query(query, scan_time = 10L, proto = c("ipv4", "ipv6"))
bjr_query(query, scan_time = 10L, proto = c("ipv4", "ipv6"))
mdns_query(query, scan_time = 10L, proto = c("ipv4", "ipv6"))
}
\arguments{
\item{query}{service to look for}
\item{scan_time}{how long to scan for services; default is 10 and
should not really be that much lower in most networks.}
\item{proto}{"\code{ipv4}" or "\code{ipv6}"}
}
\value{
data frame
}
\description{
Look for a particular service

18
src/RcppExports.cpp

@ -6,32 +6,34 @@
using namespace Rcpp;
// int_bnjr_discover
std::string int_bnjr_discover(int scan_time);
RcppExport SEXP _bonjour_int_bnjr_discover(SEXP scan_timeSEXP) {
std::string int_bnjr_discover(int scan_time, std::string proto);
RcppExport SEXP _bonjour_int_bnjr_discover(SEXP scan_timeSEXP, SEXP protoSEXP) {
BEGIN_RCPP
Rcpp::RObject rcpp_result_gen;
Rcpp::RNGScope rcpp_rngScope_gen;
Rcpp::traits::input_parameter< int >::type scan_time(scan_timeSEXP);
rcpp_result_gen = Rcpp::wrap(int_bnjr_discover(scan_time));
Rcpp::traits::input_parameter< std::string >::type proto(protoSEXP);
rcpp_result_gen = Rcpp::wrap(int_bnjr_discover(scan_time, proto));
return rcpp_result_gen;
END_RCPP
}
// int_bnjr_query
std::string int_bnjr_query(std::string q, int scan_time);
RcppExport SEXP _bonjour_int_bnjr_query(SEXP qSEXP, SEXP scan_timeSEXP) {
std::string int_bnjr_query(std::string q, int scan_time, std::string proto);
RcppExport SEXP _bonjour_int_bnjr_query(SEXP qSEXP, SEXP scan_timeSEXP, SEXP protoSEXP) {
BEGIN_RCPP
Rcpp::RObject rcpp_result_gen;
Rcpp::RNGScope rcpp_rngScope_gen;
Rcpp::traits::input_parameter< std::string >::type q(qSEXP);
Rcpp::traits::input_parameter< int >::type scan_time(scan_timeSEXP);
rcpp_result_gen = Rcpp::wrap(int_bnjr_query(q, scan_time));
Rcpp::traits::input_parameter< std::string >::type proto(protoSEXP);
rcpp_result_gen = Rcpp::wrap(int_bnjr_query(q, scan_time, proto));
return rcpp_result_gen;
END_RCPP
}
static const R_CallMethodDef CallEntries[] = {
{"_bonjour_int_bnjr_discover", (DL_FUNC) &_bonjour_int_bnjr_discover, 1},
{"_bonjour_int_bnjr_query", (DL_FUNC) &_bonjour_int_bnjr_query, 2},
{"_bonjour_int_bnjr_discover", (DL_FUNC) &_bonjour_int_bnjr_discover, 2},
{"_bonjour_int_bnjr_query", (DL_FUNC) &_bonjour_int_bnjr_query, 3},
{NULL, NULL, 0}
};

37
src/bonjour-main.cpp

@ -19,7 +19,7 @@ using namespace Rcpp;
static char addrbuffer[64];
static char namebuffer[256];
static char sendbuffer[256];
//static char sendbuffer[256];
static mdns_record_txt_t txtbuffer[128];
typedef struct {
@ -110,6 +110,13 @@ static int query_callback(int sock, const struct sockaddr* from, size_t addrlen,
mdns_record_srv_t srv = mdns_record_parse_srv(data, size, offset, length,
namebuffer, sizeof(namebuffer));
rec = rec + ", \"type\": \"SRV\"";
rec = rec + ", \"srv_name\": \"" + std::string(srv.name.str, srv.name.length) + "\"";
rec = rec + ", \"srv_priority\": " + std::to_string(srv.priority) + "";
rec = rec + ", \"srv_weight\": " + std::to_string(srv.weight) + "";
rec = rec + ", \"srv_port\": " + std::to_string(srv.port) + "";
// printf("%.*s : %s SRV %.*s priority %d weight %d port %d\n",
// MDNS_STRING_FORMAT(fromaddrstr), entrytype,
// MDNS_STRING_FORMAT(srv.name), srv.priority, srv.weight, srv.port);
@ -193,20 +200,22 @@ static int query_callback(int sock, const struct sockaddr* from, size_t addrlen,
}
// [[Rcpp::export]]
std::string int_bnjr_discover(int scan_time = 10L) {
std::string int_bnjr_discover(int scan_time = 10L, std::string proto = "ipv4") {
#ifdef _WIN32
WORD versionWanted = MAKEWORD(1, 1);
WSADATA wsaData;
if (WSAStartup(versionWanted, &wsaData)) {
printf("Failed to initialize WinSock\n");
Rf_warning("Failed to initialize WinSock\n");
return();
}
#endif
if (!((proto == "ipv4") || (proto == "ipv6"))) proto = "ipv4";
size_t capacity = 2048;
void* buffer = malloc(capacity);
void* user_data = 0;
//void* user_data = 0;
size_t records;
std::string out;
@ -214,15 +223,15 @@ std::string int_bnjr_discover(int scan_time = 10L) {
std::FILE* tmpf = std::tmpfile();
int port = 0;
int sock = mdns_socket_open_ipv4(port);
int sock = (proto == "ipv4") ? mdns_socket_open_ipv4(port) : mdns_socket_open_ipv6(port);
if (sock < 0) {
printf("Failed to open socket: %s\n", strerror(errno));
Rf_warning("Failed to open socket: %s\n", strerror(errno));
goto quit_int_bnjr_discover;
}
if (mdns_discovery_send(sock)) {
printf("Failed to send DNS-DS discovery: %s\n", strerror(errno));
Rf_warning("Failed to send DNS-DS discovery: %s\n", strerror(errno));
goto quit_int_bnjr_discover;
}
@ -265,20 +274,22 @@ std::string int_bnjr_discover(int scan_time = 10L) {
}
// [[Rcpp::export]]
std::string int_bnjr_query(std::string q, int scan_time = 5L) {
std::string int_bnjr_query(std::string q, int scan_time = 5L, std::string proto = "ipv4") {
#ifdef _WIN32
WORD versionWanted = MAKEWORD(1, 1);
WSADATA wsaData;
if (WSAStartup(versionWanted, &wsaData)) {
printf("Failed to initialize WinSock\n");
Rf_warning("Failed to initialize WinSock\n");
return();
}
#endif
if (!((proto == "ipv4") || (proto == "ipv6"))) proto = "ipv4";
size_t capacity = 2048;
void* buffer = malloc(capacity);
void* user_data = 0;
//void* user_data = 0;
size_t records;
std::FILE* tmpf = std::tmpfile();
@ -286,17 +297,17 @@ std::string int_bnjr_query(std::string q, int scan_time = 5L) {
std::string out;
int port = 0;
int sock = mdns_socket_open_ipv4(port);
int sock = (proto == "ipv4") ? mdns_socket_open_ipv4(port) : mdns_socket_open_ipv6(port);
if (sock < 0) {
printf("Failed to open socket: %s\n", strerror(errno));
Rf_warning("Failed to open socket: %s\n", strerror(errno));
goto quit_int_bnjr_query_send;
}
if (mdns_query_send(sock, MDNS_RECORDTYPE_PTR,
q.c_str(), q.length(),
buffer, capacity)) {
printf("Failed to send mDNS query: %s\n", strerror(errno));
Rf_warning("Failed to send mDNS query: %s\n", strerror(errno));
goto quit_int_bnjr_query_send;
}

22
src/mdns.h

@ -732,10 +732,10 @@ mdns_discovery_recv(int sock, void* buffer, size_t capacity,
size_t offset = (size_t)((char*)data - (char*)buffer);
records += mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
MDNS_ENTRYTYPE_AUTHORITY, transaction_id, authority_rrs,
MDNS_ENTRYTYPE_AUTHORITY, transaction_id, authority_rrs,
callback, user_data);
records += mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
MDNS_ENTRYTYPE_ADDITIONAL, transaction_id, additional_rrs,
MDNS_ENTRYTYPE_ADDITIONAL, transaction_id, additional_rrs,
callback, user_data);
return records;
@ -757,15 +757,15 @@ mdns_socket_listen(int sock, void* buffer, size_t capacity,
return 0;
size_t data_size = (size_t)ret;
size_t records = 0;
//size_t records = 0;
uint16_t* data = (uint16_t*)buffer;
uint16_t transaction_id = ntohs(*data++);
uint16_t flags = ntohs(*data++);
uint16_t questions = ntohs(*data++);
uint16_t answer_rrs = ntohs(*data++);
uint16_t authority_rrs = ntohs(*data++);
uint16_t additional_rrs = ntohs(*data++);
//uint16_t answer_rrs = ntohs(*data++);
//uint16_t authority_rrs = ntohs(*data++);
//uint16_t additional_rrs = ntohs(*data++);
size_t parsed = 0;
for (int iquestion = 0; iquestion < questions; ++iquestion) {
@ -918,13 +918,13 @@ mdns_query_recv(int sock, void* buffer, size_t capacity,
size_t records = 0;
size_t offset = MDNS_POINTER_DIFF(data, buffer);
records += mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
MDNS_ENTRYTYPE_ANSWER, transaction_id, answer_rrs,
MDNS_ENTRYTYPE_ANSWER, transaction_id, answer_rrs,
callback, user_data);
records += mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
MDNS_ENTRYTYPE_AUTHORITY, transaction_id, authority_rrs,
MDNS_ENTRYTYPE_AUTHORITY, transaction_id, authority_rrs,
callback, user_data);
records += mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
MDNS_ENTRYTYPE_ADDITIONAL, transaction_id, additional_rrs,
MDNS_ENTRYTYPE_ADDITIONAL, transaction_id, additional_rrs,
callback, user_data);
return records;
}
@ -965,7 +965,7 @@ mdns_query_answer(int sock, const void* address, size_t address_size, void* buff
*udata++ = htons(MDNS_CLASS_IN);
data = udata;
remain = capacity - MDNS_POINTER_DIFF(data, buffer);
//Fill in answers
//PTR record for service
data = mdns_string_make_ref(data, remain, service_offset);
@ -1165,7 +1165,7 @@ mdns_record_parse_txt(const void* buffer, size_t size, size_t offset, size_t len
++parsed;
}
return parsed;
return parsed;
}
#ifdef _WIN32

Loading…
Cancel
Save