...
- Capture Point. This is defined as one of IP network interfaces available on the host machine PLUS the IP version of packets that we want to capture (IPv4 or IPv6). So, for every NIC installed there can be 2 capture points configured - one for IPv4, and one for IPv6. Capture Point concept is defined simply because the underlying capture technologies require to choose one adapter AND one IP version to setup the packet capture. There will be various ways to identify a Capture Point. The simplest way to point to a particular capture point is to provide a IP address string. Btcap will then understand whether it is IPv4 or IPv6, and then identify the network interface that has the specified IP address. If none of the local IP interfaces have the specified address, then an attempt to start capture will fail.
- Capture Session. This describes the process of capturing network traffic from a single Capture Point. An executable using btcap library may start multiple capture sessions if necessary. With appropriate configuration, some or all of them can capture from the same Capture Point.
- Capture Session Config. This term describes the set of parameters that defines the session. It is primarily defined as a C structure BTCAP_SessionConfig. That structure can be initialized in the code or loaded from a config file. That adds flexibility to the solution. If the code utilizing btcap library is a standalone command line program, it is comfortable to load session config from the file. On the other hand, if that code is part of a bigger system such as SR140 server, it is perhaps easier to fill the config structure from the code. In the config file, each line follows name=value pattern.
Note: it is possible to extend the above config file format to have multiple sessions configured in one file. Config file could have sections named like this: [wlan0-v6], [eth0-v4], and so on. Each section would hold one session config. Reading such config file would have started all the sessions. Do we need this? Or is it too complicated?
Session Config File Overview
...
Basic API
With the terms defined above, the exposed API is very simple, and is the same for Windows and Linux. There are only 2 C functions exported from the library. One of them starts new capture session, the other eventually stops it. Capture session is configured as a sections in btcap config file. The config parameters include capture point, output directory, capture filters, and more. Btcap config file is described in details later in this document.
With this basic API, it is user's responsibility to dynamically load the btcap library and locate exported functions. Later in this document, a simplified level C++ API is described which incapsulates loading library bookkeeping.
// Start one Capture Session configured in the config file section named sectionName. Session ID is returned in *sessionID.
int btcap_start(const char* configFilePath, const char* sectionName, int* sessionID);
// Stop Capture Session identified with sessionID.
int btcap_stop(int sessionID);
Both methods return 0 on success or a non-zero error code.
To start a capture session the user calls btcap_start() providing (a) a valid path to a btcap config file and (b) a valid section name within that file.
First, btcap_start() attempts to (a) open the config file, (b) read the section in the file, (c) read session parameters from that section, and (d) validate session parameters. If any of that fails with appropriate error code.
If all required parameters are read from the config file, btcap_start() attempts to start the capture session in a separate "capture thread". btcap_start() itself returns as soon as the capture thread successfully starts. If the capture cannot start for whatever reason, then the btcap_start() will return an error code, and the capture thread will not exist upon return. So btcap_start() is not blocking.
On success, btcap_start() fills the sessionID with the new session's ID. That is an opaque identifier of the session, similar to Unix file descriptor. It is later used in btcap_stop().
To stop a capture session the user calls btcap_stop() providing the ID of the previously saved session. btcap_stop() signals the capture thread to stop and waits until it is done before returning.
Basic Usage Scenario
Here is the basic sequence of operations utilizing the btcap library (in pseudo-code).
// The code loading btcap library and obtaining exported entry point pointers by names is omitted. If loading failed, the program exits.
const char* configFilePath = ".\btcap.cfg"; // Config file path for this session
const char* configFileSection = "wlan0-ipv4"; // Config file section name
// Start capture session
int sessionID = 0;
int rc = btcap_start(configFilePath, configFileSection, &sessionID);
if(rc)
return 1;
// Session started in separate thread. Do other stuff...
// ...
// Later stop the capture session
btcap_stop(sessionID);
// Unload btcap library
Btcap Config File Overview
(In progress...)
Btcap config file has the same format as SR140 call control file. It consists of sections. Section names can be anything in square brackets. Each section configures one capture session. btcap_start() API (described earlier) takes both config file path and section name as arguments.
One section defines one capture session which maps to one capture point There can be more than one sections configured for the same capture point.
The following parameters can be configured in a section.
capture_ip
: IPv4 or IPv6 address of local network interface, defining the capture point. Example: capture_ip = 192.168.5.111
...
More parameters will be added as necessary.
...
Higher level API
...
With the terms defined above, the exposed API is very simple. The API is the same for Windows and Linux. There are only a few C-style entry points exported from the library.
int btcap_start(const BTCAP_SessionConfig* config, int* sessionID); // Start Capture Session. Session ID is returned in *sessionID.
int btcap_stop(int sessionID); // Stop Capture Session with sessionID.
int btcap_read_config(const char* configFilePath, BTCAP_SessionConfig* config); // Read config file into the config structure.
All 3 methods return 0 on success or a non-zero error code.
To start a capture session, the user calls btcap_start() providing a pointer to initialized BTCAP_SessionConfig structure. btcap_start() attempts to start the capture session in a separate "capture thread". btcap_start() itself returns as soon as the capture thread successfully starts. If the capture cannot start for whatever reason, then the btcap_start() will return an error code, and the capture thread will not exist upon return. So btcap_start() is not blocking.
To stop a capture session, the user calls btcap_stop() providing the ID of the previously saved session. btcap_stop() signals the capture thread to stop and waits until it is done before returning.
btcap_read_config() API initializes the instance of BTCAP_SessionConfig structure referenced by its 2nd argument with the session config from the file at configFilePath.
Basic Usage Scenario
Here is the basic sequence of operations utilizing the btcap library (in pseudo-code).
---
// Load library and obtain exported entry point pointers by names. If load failed, exit.
// Config file path for this session
const char* configFilePath = ".\btcap.cfg";
// Allocate config structure
BTCAP_SessionConfig cfg = {};
// Optional: Initialize config structure from a config file path obtained/declared earlier. (Alternatively, just initialize all fields from the code).
btcap_read_config(configFilePath, &cfg);
// Start capture session
int sessionID = 0;
btcap_start(&cfg, &sessionID);
// Session started in separate thread. Do other stuff...
// Later stop the capture session
btcap_stop(sessionID);
// Unload the library
-----
Higher level API - BTCapHelper
A higher level API in form of class BTCapHelper was created. It's done mainly to hide the technical details of loading library, and also to hide differences in that area between platforms.
...
Usage scenario with BTCapHelper
Here is the fragment of using that higher level API:
...
- BTCapHelper
A higher level C++ API in form of class BTCapHelper was created mainly to hide the technical details of loading library and also hide the differences in that area between OS platforms. Here is the class definition.
class BTCapHelper
{
public:
virtual ~BTCapHelper() {}
virtual int Start(const char* configFilePath, const char* configFileSection) = 0;
virtual int Stop() = 0;
};
bool BTCap_isAvailable(const char* pathToLibrary);
BTCapHelper* BTCap_GetHelper(const char* pathToLibrary);
Here, BTCap_GetHelper() is the factory function that will create an instance of BTCapHelper-derived platform-dependent implementation.
The BTCapHelper::Start() will (a) load the library, (b) find and save function pointers for btcap_start and btcap_stop, and (c) call btcap_start(). BTCapHelper will remember the sessionID.
The BTCapHelper::Stop() will (a) call btcap_stop() then (b) unload the library.
Usage scenario with BTCapHelper
Here is the complete command line program for Windows that utilizes BTCapHelper API.
static bool g_exit = false;
// Console CTRL handler function will be called on separate thread
static BOOL WINAPI console_ctrl_handler(DWORD dwCtrlType)
{
switch (dwCtrlType)
{
case CTRL_C_EVENT: // Ctrl+C
case CTRL_BREAK_EVENT: // Ctrl+Break
case CTRL_CLOSE_EVENT: // Closing the console window
g_exit = true;
return TRUE;
}
return FALSE;
}
#include "../include/btcap-helper.h"
#ifdef WIN32
const char* libraryPath = "./btcap.dll";
#else
const char* libraryPath = "./btcap.so";
#endif
int main(int argc, char* argv[])
{
// TODO: pass thisthese as a command line argumentarguments.
const char* btcapConfigPath = "./btcap.cfg";
const char* btcapConfigSection = "wlan0-ipv4";
printf("Checking if BTCap is available...\n");
bool ok = BTCap_isAvailable(libraryPath);
if (!ok)
{
printf(" BTCap is NOT available. Exiting.\n");
return 10;
}
printf(" BTCap is available.\n");
int rc;
BTCapHelper* btcap = BTCap_GetHelper(libraryPath);
BTCAP_SessionConfig btcapConfig = {0};
printf("ReadingStarting btcap session config file (%s) ...\n", btcapConfigPath);
rc = btcap->ReadConfig>Start(btcapConfigPath, &btcapConfigbtcapConfigSection);
printf("Starting btcap session...\n");if(rc)
rc{
= btcap->Start(&btcapConfig);
#ifdef WIN32
SetConsoleCtrlHandlerprintf(console_ctrl_handler, TRUE);
#else"btcap_start FAILED. Exiting.\n");
signal(SIGINT, sig_handler);
signal(SIGHUP, sig_handler)return 11;
signal(SIGSTOP, sig_handler);}
signal(SIGKILL, sig_handler);
signal(SIGTERM, sig_handlerSetConsoleCtrlHandler(console_ctrl_handler, TRUE);
#endif
printf("Running btcap session...\n");
while (!g_exit)
{
// Do other stuff
Sleep(1000);
}
printf("Stopping btcap session...\n");
btcap->Stop();
delete btcap;
printf("Exiting...\n");
return 0;
}
----
Implementation Overview
Questions
...