Browse Source

some more shorcut/helpers

batman
boB Rudis 10 months ago
parent
commit
bec27460a6
No known key found for this signature in database GPG Key ID: 1D7529BE14E2BBA9
  1. 6
      DESCRIPTION
  2. 8
      NAMESPACE
  3. 59
      R/pcap-to-json.R
  4. 50
      R/read-json.R
  5. 3
      R/tsharrk-package.R
  6. 14
      R/utils-pipe.R
  7. 11
      README.Rmd
  8. 67
      README.md
  9. 31
      man/pcap_to_json.Rd
  10. 20
      man/pipe.Rd
  11. 21
      man/ts_read_json.Rd

6
DESCRIPTION

@ -23,7 +23,9 @@ Depends:
Imports:
utils,
arrow,
ndjson,
tools
tools,
stringi,
RcppSimdJson,
magrittr
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.1.1

8
NAMESPACE

@ -1,12 +1,18 @@
# Generated by roxygen2: do not edit by hand
S3method(print,tshark_json)
export("%>%")
export(find_tshark)
export(get_tshark)
export(packet_summary)
export(pcap_to_json)
export(ts_read_json)
export(tshark_exec)
export(tshark_hosts)
import(RcppSimdJson)
import(arrow)
import(ndjson)
import(stringi)
importFrom(magrittr,"%>%")
importFrom(tools,file_ext)
importFrom(tools,file_path_sans_ext)
importFrom(utils,browseURL)

59
R/pcap-to-json.R

@ -0,0 +1,59 @@
#' Convert an entire PCAP file to JSON
#'
#' @param pcap path to PCAP file ([path.expand()] will be called on this value)
#' @param json path (including filename) to the location where you want the JSON
#' file stored ([path.expand()] will be called on this value)
#' @param protos character vector of protocols to include. (default is all)
#' @param include_child_nodes if `protos` is specified, this logical parameter
#' (default `FALSE`) controls whether child nodes are included.
#' @return (expanded) path to `json` (invisibly)
#' @export
#' @examples
#' tryCatch(
#' pcap_to_json(system.file("pcap", "http.pcap", package = "tsharrk"), tempfile()),
#' error = function(e) message("No tshark")
#' )
pcap_to_json <- function(pcap, json, protos = c(), include_child_nodes = FALSE) {
pcap <- path.expand(pcap[1])
if (!file.exists(pcap)) {
stop(sprintf("Cannont locate %s", pcap), call.=FALSE)
}
json <- path.expand(json[1])
if (!dir.exists(dirname(json))) {
stop(sprintf("Directory %s does not exist", dirname(json)), call.=FALSE)
}
errf <- tempfile()
on.exit(unlink(errf))
protos <- unique(trimws(tolower(as.character(protos))))
if (length(protos)) {
j <- if (include_child_nodes) "-J" else "-j"
protos <- c(j, sprintf("'%s'", paste0(protos, collapse = " ")))
}
args <- c("-T", "json", protos, "-r", pcap)
# cat(find_tshark(), args, "\n", sep=" ")
system2(
command = find_tshark(),
args = args,
stderr = errf,
stdout = json
) -> res
if (res != 0) {
stop(
sprintf("Error creating JSON from PCAP. See %s for more information.", errf),
call.=FALSE
)
}
invisible(json)
}

50
R/read-json.R

@ -0,0 +1,50 @@
#' Read in a JSON file created with [pcap_to_json()]
#'
#' @param json path to JSON output from [pcap_to_json()]. [path.expand()] will be
#' called on this value.
#' @return `list` classed as `tshark_json` for better `print`ing.
#' @export
ts_read_json <- function(json) {
json <- path.expand(json[1])
if (!file.exists(json)) {
stop(sprintf("Cannont locate %s", json), call.=FALSE)
}
RcppSimdJson::fload(
json = json,
empty_array = list(),
empty_object = list(),
single_null = list()
) -> res
class(res) <- c("tshark_json", "list")
invisible(res)
}
#' @rdname ts_read_json
#' @export
print.tshark_json <- function(x, ...) {
info <- sprintf("Capture: %s", x$`_index`[1])
cat(info, "\n", strrep("─", nchar(info)), "\n", sep="")
lapply(x$`_source`, function(.x) names(.x$layers)) %>%
sapply(paste0, collapse = " ── ") -> frames
cat(
paste(
sprintf("%s.", stri_pad_left(
str = 1:length(frames),
width = nchar(as.character(length(frames))),
pad = " "
)),
frames, sep = " "
),
sep = "\n"
)
}

3
R/tsharrk-package.R

@ -10,7 +10,8 @@
#' @keywords internal
#' @author Bob Rudis (bob@@rud.is)
#' @import arrow
#' @import ndjson
#' @import RcppSimdJson
#' @import stringi
#' @importFrom utils browseURL help read.csv tail
#' @importFrom tools file_path_sans_ext file_ext
"_PACKAGE"

14
R/utils-pipe.R

@ -0,0 +1,14 @@
#' Pipe operator
#'
#' See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details.
#'
#' @name %>%
#' @rdname pipe
#' @keywords internal
#' @export
#' @importFrom magrittr %>%
#' @usage lhs \%>\% rhs
#' @param lhs A value or the magrittr placeholder.
#' @param rhs A function call using the magrittr semantics.
#' @return The result of calling `rhs(lhs)`.
NULL

11
README.Rmd

@ -57,6 +57,17 @@ as_tibble(
)
```
```{r ex-03}
tf <- tempfile()
pcap_to_json(system.file("pcap", "http.pcap", package = "tsharrk"), json = tf)
http_cap <- ts_read_json(tf)
http_cap
unlink(tf)
```
## Code of Conduct
Please note that this project is released with a Contributor Code of Conduct.

67
README.md

@ -33,6 +33,8 @@ The following functions are implemented:
- `find_tshark`: Find the tshark binary
- `get_tshark`: Get tshark
- `packet_summary`: Extract packet summary table (if any) from a PCAP
- `pcap_to_json`: Convert an entire PCAP file to JSON
- `ts_read_json`: Read in a JSON file created with pcap_to_json()
- `tshark_exec`: Call the tshark binary with optional custom
environment variables and options
- `tshark_hosts`: Extract hostname/IP table (if any) from a PCAP
@ -64,10 +66,10 @@ packageVersion("tsharrk")
| Lang | # Files | (%) | LoC | (%) | Blank lines | (%) | # Lines | (%) |
|:-----|--------:|-----:|----:|-----:|------------:|-----:|--------:|-----:|
| R | 7 | 0.35 | 108 | 0.36 | 33 | 0.29 | 65 | 0.33 |
| YAML | 2 | 0.10 | 27 | 0.09 | 6 | 0.05 | 2 | 0.01 |
| Rmd | 1 | 0.05 | 13 | 0.04 | 18 | 0.16 | 32 | 0.16 |
| SUM | 10 | 0.50 | 148 | 0.50 | 57 | 0.50 | 99 | 0.50 |
| R | 10 | 0.38 | 172 | 0.40 | 56 | 0.33 | 102 | 0.37 |
| YAML | 2 | 0.08 | 27 | 0.06 | 6 | 0.04 | 2 | 0.01 |
| Rmd | 1 | 0.04 | 18 | 0.04 | 22 | 0.13 | 34 | 0.12 |
| SUM | 13 | 0.50 | 217 | 0.50 | 84 | 0.50 | 138 | 0.50 |
clock Package Metrics for tsharrk
@ -100,6 +102,63 @@ as_tibble(
## # … with 33 more rows
```
``` r
tf <- tempfile()
pcap_to_json(system.file("pcap", "http.pcap", package = "tsharrk"), json = tf)
## /opt/homebrew/bin/tshark -T json -r /Library/Frameworks/R.framework/Versions/4.1-arm64/Resources/library/tsharrk/pcap/http.pcap
http_cap <- ts_read_json(tf)
http_cap
## Capture: packets-2004-05-13
## ───────────────────────────
## 1. frame ── eth ── ip ── tcp
## 2. frame ── eth ── ip ── tcp
## 3. frame ── eth ── ip ── tcp
## 4. frame ── eth ── ip ── tcp ── http
## 5. frame ── eth ── ip ── tcp
## 6. frame ── eth ── ip ── tcp
## 7. frame ── eth ── ip ── tcp
## 8. frame ── eth ── ip ── tcp
## 9. frame ── eth ── ip ── tcp
## 10. frame ── eth ── ip ── tcp
## 11. frame ── eth ── ip ── tcp
## 12. frame ── eth ── ip ── tcp
## 13. frame ── eth ── ip ── udp ── dns
## 14. frame ── eth ── ip ── tcp
## 15. frame ── eth ── ip ── tcp
## 16. frame ── eth ── ip ── tcp
## 17. frame ── eth ── ip ── udp ── dns
## 18. frame ── eth ── ip ── tcp ── http
## 19. frame ── eth ── ip ── tcp
## 20. frame ── eth ── ip ── tcp
## 21. frame ── eth ── ip ── tcp
## 22. frame ── eth ── ip ── tcp
## 23. frame ── eth ── ip ── tcp
## 24. frame ── eth ── ip ── tcp
## 25. frame ── eth ── ip ── tcp
## 26. frame ── eth ── ip ── tcp
## 27. frame ── eth ── ip ── tcp ── tcp.segments ── http ── data-text-lines
## 28. frame ── eth ── ip ── tcp
## 29. frame ── eth ── ip ── tcp
## 30. frame ── eth ── ip ── tcp
## 31. frame ── eth ── ip ── tcp
## 32. frame ── eth ── ip ── tcp
## 33. frame ── eth ── ip ── tcp
## 34. frame ── eth ── ip ── tcp
## 35. frame ── eth ── ip ── tcp
## 36. frame ── eth ── ip ── tcp
## 37. frame ── eth ── ip ── tcp
## 38. frame ── eth ── ip ── tcp ── tcp.segments ── http ── xml
## 39. frame ── eth ── ip ── tcp
## 40. frame ── eth ── ip ── tcp
## 41. frame ── eth ── ip ── tcp
## 42. frame ── eth ── ip ── tcp
## 43. frame ── eth ── ip ── tcp
unlink(tf)
```
## Code of Conduct
Please note that this project is released with a Contributor Code of

31
man/pcap_to_json.Rd

@ -0,0 +1,31 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/pcap-to-json.R
\name{pcap_to_json}
\alias{pcap_to_json}
\title{Convert an entire PCAP file to JSON}
\usage{
pcap_to_json(pcap, json, protos = c(), include_child_nodes = FALSE)
}
\arguments{
\item{pcap}{path to PCAP file (\code{\link[=path.expand]{path.expand()}} will be called on this value)}
\item{json}{path (including filename) to the location where you want the JSON
file stored (\code{\link[=path.expand]{path.expand()}} will be called on this value)}
\item{protos}{character vector of protocols to include. (default is all)}
\item{include_child_nodes}{if \code{protos} is specified, this logical parameter
(default \code{FALSE}) controls whether child nodes are included.}
}
\value{
(expanded) path to \code{json} (invisibly)
}
\description{
Convert an entire PCAP file to JSON
}
\examples{
tryCatch(
pcap_to_json(system.file("pcap", "http.pcap", package = "tsharrk"), tempfile()),
error = function(e) message("No tshark")
)
}

20
man/pipe.Rd

@ -0,0 +1,20 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/utils-pipe.R
\name{\%>\%}
\alias{\%>\%}
\title{Pipe operator}
\usage{
lhs \%>\% rhs
}
\arguments{
\item{lhs}{A value or the magrittr placeholder.}
\item{rhs}{A function call using the magrittr semantics.}
}
\value{
The result of calling \code{rhs(lhs)}.
}
\description{
See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details.
}
\keyword{internal}

21
man/ts_read_json.Rd

@ -0,0 +1,21 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/read-json.R
\name{ts_read_json}
\alias{ts_read_json}
\alias{print.tshark_json}
\title{Read in a JSON file created with \code{\link[=pcap_to_json]{pcap_to_json()}}}
\usage{
ts_read_json(json)
\method{print}{tshark_json}(x, ...)
}
\arguments{
\item{json}{path to JSON output from \code{\link[=pcap_to_json]{pcap_to_json()}}. \code{\link[=path.expand]{path.expand()}} will be
called on this value.}
}
\value{
\code{list} classed as \code{tshark_json} for better \code{print}ing.
}
\description{
Read in a JSON file created with \code{\link[=pcap_to_json]{pcap_to_json()}}
}
Loading…
Cancel
Save