Search
Searching CloudShark via the API is one of the most powerful features. It is also one of the more complex methods in the API. With API search, you can build tools and automation around your CloudShark repository.
Quick Example
The API uses the GET
HTTP method. If you’re using curl
on the
command line, you may need to specify that method using the -X
option.
curl -XGET "https://www.cloudshark.org/api/v1/<token>/search?search[tags][]=Boston"
Introduction to Nested Query Strings
Nested Query Strings are a way of translating complex data structures into a string that can be sent along with an HTTP requests. They make use of a lot of square-brackets and can represent key-value pairs, hashes, and arrays all inside of a single flat string.
Examples
A key-value pair is very simple. foo=22
is translated directly. The
variable ‘foo’ is assigned to the value 22. Of course, when using these
in an HTTP request, items should be encoded to avoid special characters
and spaces.
Arrays
An array is translated into a series of parameters. Consider the following:
myArray = [1,2,3]
This is translated into 3 parameters that have the same name and have square brackets attached:
myArray[]=1&myArray[]=2&myArray[]=3
When the server receives this, it builds up an Array holding all 3 values.
Hashes
Hashes can store a number of key-value pairs within one variable. In Ruby, these look like this:
myHash = { 'one' => 1, 'two' => 2, 'three' => 3 }
Translated into our Nested Query String it looks like this:
myHash[one]=1&myHash[two]=2&myHash[three]=3
Complex Structures
These structures can get complex when you start building them up and combining them. Consider a Hash that has elements that are either simple values, or arrays! Once again in Ruby:
myHash = {
'myArray' => [1,2,3],
'myValue' => 4
}
This is translated into the following:
myHash[myArray][]=1&myHash[myArray][]=2&myHash[myArray][]=3&myHash[myValue]=4
These URLs can become really difficult to read when the square brackets are encoded as %5B%5D. It may be easier to write them out with [ and ], and let whatever HTTP client you are using do the conversion for you.
Existing Libraries
Luckily, you don’t need to do all this translation yourself. Programming languages can help with the translation, and there are probably packages out there for your favorite.
Ruby
Ruby is our favorite language, and CloudShark is written mostly in Ruby.
Internally, it uses the Rack::Utils
module to parse the parameter
string sent to it. There are two methods for translating these strings
to and from objects.
require 'rack'
# convert to nested query from a Hash of key-value pairs
post_data = Rack::Utils.build_nested_query(myHash)
# parse a query back to a Hash
params = Rack::Utils.parse_nested_query(myString)
Search Call Structure
There are two parameters that need to be provided in order for searches
to take place on the appliance. One is the search
parameter, and the
other is called matchers
.
Search
The search
object is a key-value Hash that maps individual fields to
what value they should be matched with. The format of each one can be
specific, so be sure to match them up with the documentation below. They
can be a single value, or in some cases, an Array of values.
Matchers
For single-value fields like num_packets
or duration
etc. you need
to also specify how to match the value. Are we looking for less than
that number, more? Exactly that amount? By also specifying a collection
of matchers
for each field you’re searching for, you can tell
CloudShark exactly how to search.
Matchers must be one of the following three strings:
.eq
for exact matches.lt
for matching values less-than whats given.gt
for matching values greater-that the value
Example Search Structure
To give a quick example of a search, let’s consider asking for a list back of all the capture files on the appliance that have more than 1000 packets and are tagged with ‘noc-A’. Here’s the hash that would need to be constructed:
query = {
:search => {
:num_packets => 1000,
:tags => ['noc-A'],
:matchers => {
:num_packets => ".gt"
}
}
}
params = Rack::Utils.build_nested_query(query)
#=> "search[num_packets]=1000&search[tags][]=noc-A&search[matchers][num_packets]=.gt"
Paging and Sorting
You can store hundreds of thousands, maybe millions, of capture files within CloudShark. There has to be a way to return only the ones you’re looking for, but not all at once, and in the order that makes sense to you.
CloudShark’s main index is composed of individual pages. Search works
the same way. You can specify a limit
of the number of results
per-page to return. You can pick which page
you would like returned
for the current query, and you can affect the sort_order
of the
captures returned.
Example Pages
In addition to the search
parameter, you can also send limit
and
page
. All searches are limited to a maximum page-size of 90 results,
but you can make that number smaller if you need. The default is 50
results per-page.
To return 25 results at a time, and look at the 2nd page of all the captures tagged with “Boston”, you can use the following query:
search[tags][]=Boston&limit=25&page=2
note that the parameters limit
and page
live on their own, and
aren’t part of the search[]
parameter
Sorting
Capture results can be sorted by any of the fields that can be searched
for. A direction for the sort should also be specified. The
sort_order
field is part of the search[]
structure. Allowed sort
fields are:
created_at
(upload time)user
filename
size
num_packets
duration
data_byte_rate
data_bit_rate
avg_packet_size
avg_packet_rate
start_time
(capture start)end_time
(capture end)type
encapsulation
Sort direction is decided by either .asc
ascending low-to-high, or
.desc
descending high-to-low.
For example to search for captures tagged with “Boston” and order them by the number of packets, highest-to-lowest:
search[tags][]=Boston&search[sort_order]=num_packets.desc
Searchable Fields
Filename
- Parameter:
filename
This will perform a partial name match across the whole capture
repository. If the specified value for filename
is found in any
captures, they will be included in the result set.
Example
search[filename]=sipcall
User
- Parameter:
user
- Type: Array
The user
field is an Array that will return the capture files owned by
each user specified
. Even if only specifying a single user, you must
still use the Array notation as shown in the example.
Example
search[user][]=admin&search[user][]=guest
Group
- Parameter:
group
- Type: Array
The group
field is an Array that will return the capture files owned
by each group specified. Even if only specifying a single group, you
must still use the Array notation as shown in the example.
If you want to search for capture files that do not belong to any
groups, simple add a term that equals nothing: search[group][]=
Example
search[group][]=Admin&search[group][]=Group-B
Public Captures
- Parameter:
ispublic
Searches for capture files that are visible without needing to log-in.
Example
search[ispublic]=true
Group-Writable
- Parameter:
groupwrite
Useful in combination with the Group search, this allows you to find files that have given their group ownership write access to the file.
Example
search[groupwrite]=true
Comments and Annotations
- Parameter:
annotations
- Parameter:
hascomments
Setting either of these will return those captures that have either packet annotations, or file-wide comments saved on them.
To search the contents of individual comments, the comments
parameter
can be used directly:
- Parameter:
comments
Example
search[annotations]=true&search[hascomments]=true&search[comments]=bug+129
Tags
- Parameter:
tags
- Type: Array
- Matchers: ‘tags’
Tags are a very special search parameter. If no matcher is specified only the captures that have ALL the specified tags.
The tags
matcher can take the values AND
, or OR
. If the AND
matcher is specified then only captures with all of the specified tags
will be returned. If the OR
matcher is specified then captures with
any of the specified tags will be returned.
Example
search[tags][]=orange&search[tags][]=blue&search[matchers][tags]=and
Upload Date and Capture Date
- Parameters:
date
andcap_date
- Type: Date or Ranges
Searching by Date is very powerful. CloudShark can search either by the date the file was uploaded, or the date that the actual network capture was taken.
Date ranges need to be in the format mm/dd/yyyy-mm/dd/yyyy
to specify
a Range of dates, or just a single mm/dd/yyyy
date for a single date.
The example below searches for a capture uploaded on October 11th, that
had been captured either on October 10th or 11th.
Example
search[date]=10/11/2013&search[cap_date]=10/10/2013-10/11/2013
Upload Time and Capture Time
- Parameters:
up_time_start
,up_time_end
andcap_time_start
,cap_time_end
- Type: Times
Similar to how searching by Date works for both upload date and capture date, searching by time lets you narrow down when a file was uploaded during the day, or by when the capture file was taken. You must specify both a start and an end.
Times must be in the format h:mm AM/PM
Example
search[cap_time_start]=5:30+AM&search[cap_time_end]=6:30+AM
Encapsulation
- Parameter:
encapsulation
- Type: Array
This will find captures that have any of the specified encapsulations. If you are only searching for one, you still need to use the correct notation.
Example
search[encapsulation][]=Ethernet
Type
- Parameter:
file_type
- Type: Array
Searches for captures that match any item on the list of file types. This can be useful for finding files of a certain kind. The type must match exactly for the file to be returned.
Example
search[file_type][]=Wireshark+-+pcapng
File/Data Size
- Parameters:
size
ordata_size
- Matchers:
.eq
, .lt
, or.gt
- Type: Number of bytes
Searches either the File’s size
or the PCAP’s reported data_size
field. You must also supply a matchers
entry for the same field you
are searching for. The size parameter is specified in bytes.
Example
search[size]=2000&search[matchers][size]=.gt
Duration
- Parameter:
duration
- Matchers:
.eq
,.lt
, or.gt
- Type: Length of time in seconds
Searches for files that match then given duration in seconds, according to the matcher specified.
Example
search[duration]=300&search[matchers][duration]=.lt
Number of Packets
- Parameter:
num_packets
- Matchers:
.eq
,.lt
, or.gt
- Type: Integer number of packets
Search for files with the given number of packets according to the specified matcher.
Example
search[num_packets]=1000&search[matchers][num_packets]=.eq
Packet/Byte/Bit Rate
- Parameters:
avg_packet_rate
,data_bit_rate
,data_byte_rate
- Matchers:
.eq
,.lt
, or.gt
- Type: Integer number of packets/bits/bytes per second
Example
search[data_bit_rate]=1000&search[matchers][data_bit_rate]=.gt
Average Packet Size
- Parameters:
avg_packet_size
- Matchers:
.eq
,.lt
, or.gt
- Type: Numeric average packet size in bytes
Searches the reported average packet size of individual captures.
Example
search[avg_packet_size]=512&search[matchers][avg_packet_size]=.lt
SHA-1 Hash
- Parameters:
sha1_hash
Searches for capture files with the specified SHA-1 hash
Example
search[sha1_hash]=d75ab989ee0f76e868a41bd30fa61d14336610c4