97#include <netinet/ip.h>
98#include <netinet/tcp.h>
99#include <netinet/udp.h>
100#include <netinet/ip6.h>
103#define GENERIC_VENDOR_ID 0x0000
106#define ASTERISK_VENDOR_ID 0x0004
166#define INITIALIZE_GENERIC_HEP_IDS(hep_chunk, type) do { \
167 (hep_chunk)->vendor_id = htons(GENERIC_VENDOR_ID); \
168 (hep_chunk)->type_id = htons((type)); \
171#define INITIALIZE_GENERIC_HEP_IDS_VAR(hep_chunk, type, len) do { \
172 INITIALIZE_GENERIC_HEP_IDS((hep_chunk), (type)); \
173 (hep_chunk)->length = htons(sizeof(*(hep_chunk)) + len); \
176#define INITIALIZE_GENERIC_HEP_CHUNK(hep_item, type) do { \
177 INITIALIZE_GENERIC_HEP_IDS(&(hep_item)->chunk, (type)); \
178 (hep_item)->chunk.length = htons(sizeof(*(hep_item))); \
181#define INITIALIZE_GENERIC_HEP_CHUNK_DATA(hep_item, type, value) do { \
182 INITIALIZE_GENERIC_HEP_CHUNK((hep_item), (type)); \
183 (hep_item)->data = (value); \
195} __attribute__((packed));
200} __attribute__((packed));
205} __attribute__((packed));
210} __attribute__((packed));
215} __attribute__((packed));
220} __attribute__((packed));
225} __attribute__((packed));
239} __attribute__((packed));
269 .category =
"general",
352 if (strcasecmp(
var->name,
"uuid_type")) {
356 if (!strcasecmp(
var->value,
"channel")) {
358 }
else if (!strcasecmp(
var->value,
"call-id")) {
425 return config->general->uuid_type;
445 if (!
info->payload) {
453 info->protocol_id = IPPROTO_UDP;
465 unsigned int packet_len = 0, sock_buffer_len;
472 if (!capture_info || !
config || !hepv3_data) {
477 ast_log(
AST_LOG_NOTICE,
"Unable to send packet: Address Family mismatch between source/destination\n");
481 packet_len =
sizeof(hg_pkt);
484 memcpy(hg_pkt.
header.
id,
"\x48\x45\x50\x33", 4);
504 packet_len += (
sizeof(ipv4_src) +
sizeof(ipv4_dst));
515 packet_len += (
sizeof(ipv6_src) +
sizeof(ipv6_dst));
520 packet_len += (
sizeof(auth_key) + strlen(
config->general->capture_password));
524 packet_len += (
sizeof(capturename) + strlen(
config->general->capture_name));
527 packet_len += (
sizeof(
uuid) + strlen(capture_info->uuid));
530 packet_len += (
sizeof(payload) + capture_info->len);
540 memcpy(sock_buffer, &hg_pkt,
sizeof(hg_pkt));
541 sock_buffer_len =
sizeof(hg_pkt);
545 memcpy(sock_buffer + sock_buffer_len, &ipv4_src,
sizeof(ipv4_src));
546 sock_buffer_len +=
sizeof(ipv4_src);
547 memcpy(sock_buffer + sock_buffer_len, &ipv4_dst,
sizeof(ipv4_dst));
548 sock_buffer_len +=
sizeof(ipv4_dst);
550 memcpy(sock_buffer + sock_buffer_len, &ipv6_src,
sizeof(ipv6_src));
551 sock_buffer_len +=
sizeof(ipv6_src);
552 memcpy(sock_buffer + sock_buffer_len, &ipv6_dst,
sizeof(ipv6_dst));
553 sock_buffer_len +=
sizeof(ipv6_dst);
558 memcpy(sock_buffer + sock_buffer_len, &auth_key,
sizeof(auth_key));
559 sock_buffer_len +=
sizeof(auth_key);
560 memcpy(sock_buffer + sock_buffer_len,
config->general->capture_password, strlen(
config->general->capture_password));
561 sock_buffer_len += strlen(
config->general->capture_password);
565 memcpy(sock_buffer + sock_buffer_len, &
uuid,
sizeof(
uuid));
566 sock_buffer_len +=
sizeof(
uuid);
567 memcpy(sock_buffer + sock_buffer_len, capture_info->uuid, strlen(capture_info->uuid));
568 sock_buffer_len += strlen(capture_info->uuid);
572 memcpy(sock_buffer + sock_buffer_len, &capturename,
sizeof(capturename));
573 sock_buffer_len +=
sizeof(capturename);
574 memcpy(sock_buffer + sock_buffer_len,
config->general->capture_name, strlen(
config->general->capture_name));
575 sock_buffer_len += strlen(
config->general->capture_name);
579 memcpy(sock_buffer + sock_buffer_len, &payload,
sizeof(payload));
580 sock_buffer_len +=
sizeof(payload);
581 memcpy(sock_buffer + sock_buffer_len, capture_info->payload, capture_info->len);
582 sock_buffer_len += capture_info->len;
586 res =
ast_sendto(hepv3_data->sockfd, sock_buffer, sock_buffer_len, 0, &hepv3_data->remote_addr);
590 }
else if (res != sock_buffer_len) {
592 res, sock_buffer_len);
627 if (!
config->general->enabled) {
Asterisk main include file. File version handling, generic pbx functions.
#define ast_malloc(len)
A wrapper for malloc()
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
#define ao2_alloc(data_size, destructor_fn)
static const char config[]
Configuration option-handling.
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
@ ACO_PROCESS_ERROR
Their was an error and no changes were applied.
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
#define aco_option_register(info, name, matchtype, types, default_val, opt_type, flags,...)
Register a config option.
@ OPT_UINT_T
Type for default option handler for unsigned integers.
@ OPT_BOOL_T
Type for default option handler for bools (ast_true/ast_false)
@ OPT_STRINGFIELD_T
Type for default option handler for stringfields.
#define aco_option_register_custom(info, name, matchtype, types, default_val, handler, flags)
Register a config option.
void * aco_pending_config(struct aco_info *info)
Get pending config changes.
enum aco_process_status aco_process_config(struct aco_info *info, int reload)
Process a config info via the options registered with an aco_info.
#define ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int uuid(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Asterisk module definitions.
@ AST_MODFLAG_GLOBAL_SYMBOLS
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODULE_SUPPORT_EXTENDED
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
int ast_sockaddr_resolve_first_af(struct ast_sockaddr *addr, const char *name, int flag, int family)
Return the first entry from ast_sockaddr_resolve filtered by address family.
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
ssize_t ast_sendto(int sockfd, const void *buf, size_t len, int flags, const struct ast_sockaddr *dest_addr)
Wrapper around sendto(2) that uses ast_sockaddr.
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
struct aco_type * global_options[]
static int uuid_type_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Handler for the uuid_type attribute.
CONFIG_INFO_STANDARD(cfg_info, global_config, module_config_alloc,.files=ACO_FILES(&hepv3_conf),.pre_apply_config=hepv3_config_pre_apply,.post_apply_config=hepv3_config_post_apply,)
Register information about the configs being processed by this module.
@ CHUNK_TYPE_TIMESTAMP_USEC
@ CHUNK_TYPE_IPV4_DST_ADDR
@ CHUNK_TYPE_IPV6_SRC_ADDR
@ CHUNK_TYPE_IP_PROTOCOL_ID
@ CHUNK_TYPE_TIMESTAMP_SEC
@ CHUNK_TYPE_PROTOCOL_TYPE
@ CHUNK_TYPE_IPV4_SRC_ADDR
@ CHUNK_TYPE_CAPTURE_AGENT_NAME
@ CHUNK_TYPE_IPV6_DST_ADDR
@ CHUNK_TYPE_IP_PROTOCOL_FAMILY
@ CHUNK_TYPE_KEEP_ALIVE_TIMER
@ CHUNK_TYPE_CAPTURE_AGENT_ID
static int hep_queue_cb(void *data)
Callback function for the hep_queue_tp taskprocessor.
enum hep_uuid_type hepv3_get_uuid_type(void)
Get the preferred UUID type.
#define INITIALIZE_GENERIC_HEP_CHUNK_DATA(hep_item, type, value)
static struct ast_taskprocessor * hep_queue_tp
static void * hepv3_config_alloc(void)
HEPv3 configuration object allocation.
static struct hepv3_runtime_data * hepv3_data_alloc(struct hepv3_global_config *config)
Allocate the HEPv3 run-time data.
int hepv3_is_loaded(void)
Return whether or not we're currently loaded and active.
static AO2_GLOBAL_OBJ_STATIC(global_config)
The module configuration container.
static int reload_module(void)
Reload the module.
static void hepv3_config_post_apply(void)
Post-apply callback for the config framework.
struct aco_file hepv3_conf
static void capture_info_dtor(void *obj)
Destructor for a hepv3_capture_info object.
struct hepv3_capture_info * hepv3_create_capture_info(const void *payload, size_t len)
Create a hepv3_capture_info object.
static void module_config_dtor(void *obj)
Configuration object destructor.
static int hepv3_config_pre_apply(void)
Pre-apply callback for the config framework.
#define INITIALIZE_GENERIC_HEP_CHUNK(hep_item, type)
static int load_module(void)
Load the module.
int hepv3_send_packet(struct hepv3_capture_info *capture_info)
Send a generic packet capture to HEPv3.
static int unload_module(void)
Unload the module.
#define INITIALIZE_GENERIC_HEP_IDS_VAR(hep_chunk, type, len)
static void hepv3_config_dtor(void *obj)
static void * module_config_alloc(void)
Module config constructor.
static void hepv3_data_dtor(void *obj)
HEPv3 run-time data destructor.
static struct aco_type global_option
Routines for integration with Homer using HEPv3.
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
#define AST_STRING_FIELD(name)
Declare a string field.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
static force_inline int attribute_pure ast_strlen_zero(const char *s)
The representation of a single configuration file to be processed.
Type information about a category-level configurable object.
Socket address structure.
A ast_taskprocessor structure is a singleton by name.
Structure for variables, used for configurations and for channel variables.
struct hep_chunk_uint8 ip_proto
struct hep_chunk_uint8 proto_t
struct hep_chunk_uint16 dst_port
struct hep_chunk_uint32 capt_id
struct hep_chunk_uint32 time_sec
struct hep_chunk_uint8 ip_family
struct hep_chunk_uint16 src_port
struct hep_chunk_uint32 time_usec
Global configuration for the module.
const ast_string_field capture_password
enum hep_uuid_type uuid_type
const ast_string_field capture_name
const ast_string_field capture_address
Run-time data derived from hepv3_global_config.
struct ast_sockaddr remote_addr
The configuration settings for this module.
struct hepv3_global_config * general
An API for managing task processing threads that can be shared across modules.
struct ast_taskprocessor * ast_taskprocessor_get(const char *name, enum ast_tps_options create)
Get a reference to a taskprocessor with the specified name and create the taskprocessor if necessary.
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
@ TPS_REF_DEFAULT
return a reference to a taskprocessor, create one if it does not exist
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap) attribute_warn_unused_result
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.
int error(const char *format,...)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.