Asterisk - The Open Source Telephony Project  GIT-master-a24979a
Data Structures | Macros | Enumerations | Functions | Variables
res_hep.c File Reference

Routines for integration with Homer using HEPv3. More...

#include "asterisk.h"
#include "asterisk/module.h"
#include "asterisk/astobj2.h"
#include "asterisk/config_options.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/res_hep.h"
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip6.h>
Include dependency graph for res_hep.c:

Go to the source code of this file.

Data Structures

struct  hep_chunk
 
struct  hep_chunk_ip4
 
struct  hep_chunk_ip6
 
struct  hep_chunk_uint16
 
struct  hep_chunk_uint32
 
struct  hep_chunk_uint8
 
struct  hep_ctrl
 
struct  hep_generic
 
struct  hepv3_global_config
 Global configuration for the module. More...
 
struct  hepv3_runtime_data
 Run-time data derived from hepv3_global_config. More...
 
struct  module_config
 The configuration settings for this module. More...
 

Macros

#define ASTERISK_VENDOR_ID   0x0004
 
#define GENERIC_VENDOR_ID   0x0000
 
#define INITIALIZE_GENERIC_HEP_CHUNK(hep_item, type)
 
#define INITIALIZE_GENERIC_HEP_CHUNK_DATA(hep_item, type, value)
 
#define INITIALIZE_GENERIC_HEP_IDS(hep_chunk, type)
 
#define INITIALIZE_GENERIC_HEP_IDS_VAR(hep_chunk, type, len)
 

Enumerations

enum  hepv3_chunk_types {
  CHUNK_TYPE_IP_PROTOCOL_FAMILY = 0X0001 , CHUNK_TYPE_IP_PROTOCOL_ID = 0X0002 , CHUNK_TYPE_IPV4_SRC_ADDR = 0X0003 , CHUNK_TYPE_IPV4_DST_ADDR = 0X0004 ,
  CHUNK_TYPE_IPV6_SRC_ADDR = 0X0005 , CHUNK_TYPE_IPV6_DST_ADDR = 0X0006 , CHUNK_TYPE_SRC_PORT = 0X0007 , CHUNK_TYPE_DST_PORT = 0X0008 ,
  CHUNK_TYPE_TIMESTAMP_SEC = 0X0009 , CHUNK_TYPE_TIMESTAMP_USEC = 0X000A , CHUNK_TYPE_PROTOCOL_TYPE = 0X000B , CHUNK_TYPE_CAPTURE_AGENT_ID = 0X000C ,
  CHUNK_TYPE_KEEP_ALIVE_TIMER = 0X000D , CHUNK_TYPE_AUTH_KEY = 0X000E , CHUNK_TYPE_PAYLOAD = 0X000F , CHUNK_TYPE_PAYLOAD_ZIP = 0X0010 ,
  CHUNK_TYPE_UUID = 0X0011
}
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static AO2_GLOBAL_OBJ_STATIC (global_config)
 The module configuration container. More...
 
static AO2_GLOBAL_OBJ_STATIC (global_data)
 Current module data. More...
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static void capture_info_dtor (void *obj)
 Destructor for a hepv3_capture_info object. More...
 
 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. More...
 
static int hep_queue_cb (void *data)
 Callback function for the hep_queue_tp taskprocessor. More...
 
static void * hepv3_config_alloc (void)
 HEPv3 configuration object allocation. More...
 
static void hepv3_config_dtor (void *obj)
 
static void hepv3_config_post_apply (void)
 Post-apply callback for the config framework. More...
 
static int hepv3_config_pre_apply (void)
 Pre-apply callback for the config framework. More...
 
struct hepv3_capture_infohepv3_create_capture_info (const void *payload, size_t len)
 Create a hepv3_capture_info object. More...
 
static struct hepv3_runtime_datahepv3_data_alloc (struct hepv3_global_config *config)
 Allocate the HEPv3 run-time data. More...
 
static void hepv3_data_dtor (void *obj)
 HEPv3 run-time data destructor. More...
 
enum hep_uuid_type hepv3_get_uuid_type (void)
 Get the preferred UUID type. More...
 
int hepv3_is_loaded (void)
 Return whether or not we're currently loaded and active. More...
 
int hepv3_send_packet (struct hepv3_capture_info *capture_info)
 Send a generic packet capture to HEPv3. More...
 
static int load_module (void)
 Load the module. More...
 
static void * module_config_alloc (void)
 Module config constructor. More...
 
static void module_config_dtor (void *obj)
 Configuration object destructor. More...
 
static int reload_module (void)
 Reload the module. More...
 
static int unload_module (void)
 Unload the module. More...
 
static int uuid_type_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 Handler for the uuid_type attribute. More...
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "HEPv3 API" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_APP_DEPEND, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct aco_type global_option
 
struct aco_typeglobal_options [] = ACO_TYPES(&global_option)
 
static struct ast_taskprocessorhep_queue_tp
 
struct aco_file hepv3_conf
 

Detailed Description

Routines for integration with Homer using HEPv3.

Author
Alexandr Dubovikov alexa.nosp@m.ndr..nosp@m.dubov.nosp@m.ikov.nosp@m.@sipc.nosp@m.aptu.nosp@m.re.or.nosp@m.g
Matt Jordan mjord.nosp@m.an@d.nosp@m.igium.nosp@m..com

Definition in file res_hep.c.

Macro Definition Documentation

◆ ASTERISK_VENDOR_ID

#define ASTERISK_VENDOR_ID   0x0004

Asterisk vendor ID. Used for custom data to send to a capture node

Definition at line 103 of file res_hep.c.

◆ GENERIC_VENDOR_ID

#define GENERIC_VENDOR_ID   0x0000

Generic vendor ID. Used for HEPv3 standard packets

Definition at line 100 of file res_hep.c.

◆ INITIALIZE_GENERIC_HEP_CHUNK

#define INITIALIZE_GENERIC_HEP_CHUNK (   hep_item,
  type 
)
Value:
do { \
INITIALIZE_GENERIC_HEP_IDS(&(hep_item)->chunk, (type)); \
(hep_item)->chunk.length = htons(sizeof(*(hep_item))); \
} while (0)
static const char type[]
Definition: chan_ooh323.c:109

Definition at line 170 of file res_hep.c.

◆ INITIALIZE_GENERIC_HEP_CHUNK_DATA

#define INITIALIZE_GENERIC_HEP_CHUNK_DATA (   hep_item,
  type,
  value 
)
Value:
do { \
INITIALIZE_GENERIC_HEP_CHUNK((hep_item), (type)); \
(hep_item)->data = (value); \
} while (0)
int value
Definition: syslog.c:37

Definition at line 175 of file res_hep.c.

◆ INITIALIZE_GENERIC_HEP_IDS

#define INITIALIZE_GENERIC_HEP_IDS (   hep_chunk,
  type 
)
Value:
do { \
(hep_chunk)->vendor_id = htons(GENERIC_VENDOR_ID); \
(hep_chunk)->type_id = htons((type)); \
} while (0)
#define GENERIC_VENDOR_ID
Definition: res_hep.c:100

Definition at line 160 of file res_hep.c.

◆ INITIALIZE_GENERIC_HEP_IDS_VAR

#define INITIALIZE_GENERIC_HEP_IDS_VAR (   hep_chunk,
  type,
  len 
)
Value:
do { \
INITIALIZE_GENERIC_HEP_IDS((hep_chunk), (type)); \
(hep_chunk)->length = htons(sizeof(*(hep_chunk)) + len); \
} while (0)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

Definition at line 165 of file res_hep.c.

Enumeration Type Documentation

◆ hepv3_chunk_types

Chunk types from the HEPv3 Spec

Enumerator
CHUNK_TYPE_IP_PROTOCOL_FAMILY 

THE IP PROTOCOL FAMILY

CHUNK_TYPE_IP_PROTOCOL_ID 

THE IP PROTOCOL ID (UDP, TCP, ETC.)

CHUNK_TYPE_IPV4_SRC_ADDR 

IF IPV4, THE SOURCE ADDRESS

CHUNK_TYPE_IPV4_DST_ADDR 

IF IPV4, THE DESTINATION ADDRESS

CHUNK_TYPE_IPV6_SRC_ADDR 

IF IPV6, THE SOURCE ADDRESS

CHUNK_TYPE_IPV6_DST_ADDR 

IF IPV6, THE DESTINATION ADDRESS

CHUNK_TYPE_SRC_PORT 

THE SOURCE PORT

CHUNK_TYPE_DST_PORT 

THE DESTINATION PORT

CHUNK_TYPE_TIMESTAMP_SEC 

THE CAPTURE TIME (SECONDS)

CHUNK_TYPE_TIMESTAMP_USEC 

THE CAPTURE TIME (MICROSECONDS)

CHUNK_TYPE_PROTOCOL_TYPE 

THE PROTOCOL PACKET TYPE. SEE /REF HEPV3_CAPTURE_TYPE

CHUNK_TYPE_CAPTURE_AGENT_ID 

OUR CAPTURE AGENT ID

CHUNK_TYPE_KEEP_ALIVE_TIMER 

A KEEP ALIVE TIMER

CHUNK_TYPE_AUTH_KEY 

THE CAPTURE_PASSWORD IF DEFINED

CHUNK_TYPE_PAYLOAD 

THE ONE AND ONLY PAYLOAD

CHUNK_TYPE_PAYLOAD_ZIP 

THE ONE AND ONLY (ZIPPED) PAYLOAD

CHUNK_TYPE_UUID 

THE UUID FOR THIS PACKET

Definition at line 106 of file res_hep.c.

106  {
107 
108  /*! THE IP PROTOCOL FAMILY */
110 
111  /*! THE IP PROTOCOL ID (UDP, TCP, ETC.) */
112  CHUNK_TYPE_IP_PROTOCOL_ID = 0X0002,
113 
114  /*! IF IPV4, THE SOURCE ADDRESS */
115  CHUNK_TYPE_IPV4_SRC_ADDR = 0X0003,
116 
117  /*! IF IPV4, THE DESTINATION ADDRESS */
118  CHUNK_TYPE_IPV4_DST_ADDR = 0X0004,
119 
120  /*! IF IPV6, THE SOURCE ADDRESS */
121  CHUNK_TYPE_IPV6_SRC_ADDR = 0X0005,
122 
123  /*! IF IPV6, THE DESTINATION ADDRESS */
124  CHUNK_TYPE_IPV6_DST_ADDR = 0X0006,
125 
126  /*! THE SOURCE PORT */
127  CHUNK_TYPE_SRC_PORT = 0X0007,
128 
129  /*! THE DESTINATION PORT */
130  CHUNK_TYPE_DST_PORT = 0X0008,
131 
132  /*! THE CAPTURE TIME (SECONDS) */
133  CHUNK_TYPE_TIMESTAMP_SEC = 0X0009,
134 
135  /*! THE CAPTURE TIME (MICROSECONDS) */
136  CHUNK_TYPE_TIMESTAMP_USEC = 0X000A,
137 
138  /*! THE PROTOCOL PACKET TYPE. SEE /REF HEPV3_CAPTURE_TYPE */
139  CHUNK_TYPE_PROTOCOL_TYPE = 0X000B,
140 
141  /*! OUR CAPTURE AGENT ID */
143 
144  /*! A KEEP ALIVE TIMER */
146 
147  /*! THE CAPTURE_PASSWORD IF DEFINED */
148  CHUNK_TYPE_AUTH_KEY = 0X000E,
149 
150  /*! THE ONE AND ONLY PAYLOAD */
151  CHUNK_TYPE_PAYLOAD = 0X000F,
152 
153  /*! THE ONE AND ONLY (ZIPPED) PAYLOAD */
154  CHUNK_TYPE_PAYLOAD_ZIP = 0X0010,
155 
156  /*! THE UUID FOR THIS PACKET */
157  CHUNK_TYPE_UUID = 0X0011,
158 };
@ CHUNK_TYPE_TIMESTAMP_USEC
Definition: res_hep.c:136
@ CHUNK_TYPE_PAYLOAD_ZIP
Definition: res_hep.c:154
@ CHUNK_TYPE_IPV4_DST_ADDR
Definition: res_hep.c:118
@ CHUNK_TYPE_IPV6_SRC_ADDR
Definition: res_hep.c:121
@ CHUNK_TYPE_IP_PROTOCOL_ID
Definition: res_hep.c:112
@ CHUNK_TYPE_DST_PORT
Definition: res_hep.c:130
@ CHUNK_TYPE_TIMESTAMP_SEC
Definition: res_hep.c:133
@ CHUNK_TYPE_PROTOCOL_TYPE
Definition: res_hep.c:139
@ CHUNK_TYPE_PAYLOAD
Definition: res_hep.c:151
@ CHUNK_TYPE_IPV4_SRC_ADDR
Definition: res_hep.c:115
@ CHUNK_TYPE_IPV6_DST_ADDR
Definition: res_hep.c:124
@ CHUNK_TYPE_AUTH_KEY
Definition: res_hep.c:148
@ CHUNK_TYPE_IP_PROTOCOL_FAMILY
Definition: res_hep.c:109
@ CHUNK_TYPE_UUID
Definition: res_hep.c:157
@ CHUNK_TYPE_SRC_PORT
Definition: res_hep.c:127
@ CHUNK_TYPE_KEEP_ALIVE_TIMER
Definition: res_hep.c:145
@ CHUNK_TYPE_CAPTURE_AGENT_ID
Definition: res_hep.c:142

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 703 of file res_hep.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 703 of file res_hep.c.

◆ AO2_GLOBAL_OBJ_STATIC() [1/2]

static AO2_GLOBAL_OBJ_STATIC ( global_config  )
static

The module configuration container.

◆ AO2_GLOBAL_OBJ_STATIC() [2/2]

static AO2_GLOBAL_OBJ_STATIC ( global_data  )
static

Current module data.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 703 of file res_hep.c.

◆ capture_info_dtor()

static void capture_info_dtor ( void *  obj)
static

Destructor for a hepv3_capture_info object.

Definition at line 401 of file res_hep.c.

402 {
403  struct hepv3_capture_info *info = obj;
404 
405  ast_free(info->uuid);
406  ast_free(info->payload);
407 }
#define ast_free(a)
Definition: astmm.h:180
def info(msg)
HEPv3 Capture Info.
Definition: res_hep.h:58

References ast_free, and sip_to_pjsip::info().

Referenced by hepv3_create_capture_info().

◆ CONFIG_INFO_STANDARD()

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.

◆ hep_queue_cb()

static int hep_queue_cb ( void *  data)
static

Callback function for the hep_queue_tp taskprocessor.

Definition at line 452 of file res_hep.c.

453 {
455  RAII_VAR(struct hepv3_runtime_data *, hepv3_data, ao2_global_obj_ref(global_data), ao2_cleanup);
456  RAII_VAR(struct hepv3_capture_info *, capture_info, data, ao2_cleanup);
457  struct hep_generic hg_pkt;
458  unsigned int packet_len = 0, sock_buffer_len;
459  struct hep_chunk_ip4 ipv4_src, ipv4_dst;
460  struct hep_chunk_ip6 ipv6_src, ipv6_dst;
461  struct hep_chunk auth_key, payload, uuid;
462  void *sock_buffer;
463  int res;
464 
465  if (!capture_info || !config || !hepv3_data) {
466  return 0;
467  }
468 
469  if (ast_sockaddr_is_ipv4(&capture_info->src_addr) != ast_sockaddr_is_ipv4(&capture_info->dst_addr)) {
470  ast_log(AST_LOG_NOTICE, "Unable to send packet: Address Family mismatch between source/destination\n");
471  return -1;
472  }
473 
474  packet_len = sizeof(hg_pkt);
475 
476  /* Build HEPv3 header, capture info, and calculate the total packet size */
477  memcpy(hg_pkt.header.id, "\x48\x45\x50\x33", 4);
478 
479  INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.ip_proto, CHUNK_TYPE_IP_PROTOCOL_ID, capture_info->protocol_id);
480  INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.src_port, CHUNK_TYPE_SRC_PORT, htons(ast_sockaddr_port(&capture_info->src_addr)));
481  INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.dst_port, CHUNK_TYPE_DST_PORT, htons(ast_sockaddr_port(&capture_info->dst_addr)));
482  INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.time_sec, CHUNK_TYPE_TIMESTAMP_SEC, htonl(capture_info->capture_time.tv_sec));
483  INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.time_usec, CHUNK_TYPE_TIMESTAMP_USEC, htonl(capture_info->capture_time.tv_usec));
484  INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.proto_t, CHUNK_TYPE_PROTOCOL_TYPE, capture_info->capture_type);
485  INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.capt_id, CHUNK_TYPE_CAPTURE_AGENT_ID, htonl(config->general->capture_id));
486 
487  if (ast_sockaddr_is_ipv4(&capture_info->src_addr)) {
488  INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.ip_family,
490 
492  inet_pton(AF_INET, ast_sockaddr_stringify_addr(&capture_info->src_addr), &ipv4_src.data);
493 
495  inet_pton(AF_INET, ast_sockaddr_stringify_addr(&capture_info->dst_addr), &ipv4_dst.data);
496 
497  packet_len += (sizeof(ipv4_src) + sizeof(ipv4_dst));
498  } else {
499  INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.ip_family,
501 
503  inet_pton(AF_INET6, ast_sockaddr_stringify_addr(&capture_info->src_addr), &ipv6_src.data);
504 
506  inet_pton(AF_INET6, ast_sockaddr_stringify_addr(&capture_info->dst_addr), &ipv6_dst.data);
507 
508  packet_len += (sizeof(ipv6_src) + sizeof(ipv6_dst));
509  }
510 
511  if (!ast_strlen_zero(config->general->capture_password)) {
512  INITIALIZE_GENERIC_HEP_IDS_VAR(&auth_key, CHUNK_TYPE_AUTH_KEY, strlen(config->general->capture_password));
513  packet_len += (sizeof(auth_key) + strlen(config->general->capture_password));
514  }
515  INITIALIZE_GENERIC_HEP_IDS_VAR(&uuid, CHUNK_TYPE_UUID, strlen(capture_info->uuid));
516  packet_len += (sizeof(uuid) + strlen(capture_info->uuid));
518  capture_info->zipped ? CHUNK_TYPE_PAYLOAD_ZIP : CHUNK_TYPE_PAYLOAD, capture_info->len);
519  packet_len += (sizeof(payload) + capture_info->len);
520  hg_pkt.header.length = htons(packet_len);
521 
522  /* Build the buffer to send */
523  sock_buffer = ast_malloc(packet_len);
524  if (!sock_buffer) {
525  return -1;
526  }
527 
528  /* Copy in the header */
529  memcpy(sock_buffer, &hg_pkt, sizeof(hg_pkt));
530  sock_buffer_len = sizeof(hg_pkt);
531 
532  /* Addresses */
533  if (ast_sockaddr_is_ipv4(&capture_info->src_addr)) {
534  memcpy(sock_buffer + sock_buffer_len, &ipv4_src, sizeof(ipv4_src));
535  sock_buffer_len += sizeof(ipv4_src);
536  memcpy(sock_buffer + sock_buffer_len, &ipv4_dst, sizeof(ipv4_dst));
537  sock_buffer_len += sizeof(ipv4_dst);
538  } else {
539  memcpy(sock_buffer + sock_buffer_len, &ipv6_src, sizeof(ipv6_src));
540  sock_buffer_len += sizeof(ipv6_src);
541  memcpy(sock_buffer + sock_buffer_len, &ipv6_dst, sizeof(ipv6_dst));
542  sock_buffer_len += sizeof(ipv6_dst);
543  }
544 
545  /* Auth Key */
546  if (!ast_strlen_zero(config->general->capture_password)) {
547  memcpy(sock_buffer + sock_buffer_len, &auth_key, sizeof(auth_key));
548  sock_buffer_len += sizeof(auth_key);
549  memcpy(sock_buffer + sock_buffer_len, config->general->capture_password, strlen(config->general->capture_password));
550  sock_buffer_len += strlen(config->general->capture_password);
551  }
552 
553  /* UUID */
554  memcpy(sock_buffer + sock_buffer_len, &uuid, sizeof(uuid));
555  sock_buffer_len += sizeof(uuid);
556  memcpy(sock_buffer + sock_buffer_len, capture_info->uuid, strlen(capture_info->uuid));
557  sock_buffer_len += strlen(capture_info->uuid);
558 
559  /* Packet! */
560  memcpy(sock_buffer + sock_buffer_len, &payload, sizeof(payload));
561  sock_buffer_len += sizeof(payload);
562  memcpy(sock_buffer + sock_buffer_len, capture_info->payload, capture_info->len);
563  sock_buffer_len += capture_info->len;
564 
565  ast_assert(sock_buffer_len == packet_len);
566 
567  res = ast_sendto(hepv3_data->sockfd, sock_buffer, sock_buffer_len, 0, &hepv3_data->remote_addr);
568  if (res < 0) {
569  ast_log(AST_LOG_ERROR, "Error [%d] while sending packet to HEPv3 server: %s\n",
570  errno, strerror(errno));
571  } else if (res != sock_buffer_len) {
572  ast_log(AST_LOG_WARNING, "Failed to send complete packet to HEPv3 server: %d of %u sent\n",
573  res, sock_buffer_len);
574  res = -1;
575  }
576 
577  ast_free(sock_buffer);
578  return res;
579 }
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define ast_log
Definition: astobj2.c:42
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
static const char config[]
Definition: chan_ooh323.c:111
#define AST_LOG_WARNING
#define AST_LOG_ERROR
#define AST_LOG_NOTICE
int errno
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:517
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:286
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.
Definition: netsock2.c:614
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
Definition: netsock2.c:497
#define INITIALIZE_GENERIC_HEP_CHUNK_DATA(hep_item, type, value)
Definition: res_hep.c:175
#define INITIALIZE_GENERIC_HEP_CHUNK(hep_item, type)
Definition: res_hep.c:170
#define INITIALIZE_GENERIC_HEP_IDS_VAR(hep_chunk, type, len)
Definition: res_hep.c:165
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Run-time data derived from hepv3_global_config.
Definition: res_hep.c:252
The configuration settings for this module.
Definition: cdr.c:238
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:936
#define ast_assert(a)
Definition: utils.h:734

References ao2_cleanup, ao2_global_obj_ref, ast_assert, ast_free, ast_log, AST_LOG_ERROR, AST_LOG_NOTICE, AST_LOG_WARNING, ast_malloc, ast_sendto(), ast_sockaddr_is_ipv4(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_strlen_zero(), hep_generic::capt_id, CHUNK_TYPE_AUTH_KEY, CHUNK_TYPE_CAPTURE_AGENT_ID, CHUNK_TYPE_DST_PORT, CHUNK_TYPE_IP_PROTOCOL_FAMILY, CHUNK_TYPE_IP_PROTOCOL_ID, CHUNK_TYPE_IPV4_DST_ADDR, CHUNK_TYPE_IPV4_SRC_ADDR, CHUNK_TYPE_IPV6_DST_ADDR, CHUNK_TYPE_IPV6_SRC_ADDR, CHUNK_TYPE_PAYLOAD, CHUNK_TYPE_PAYLOAD_ZIP, CHUNK_TYPE_PROTOCOL_TYPE, CHUNK_TYPE_SRC_PORT, CHUNK_TYPE_TIMESTAMP_SEC, CHUNK_TYPE_TIMESTAMP_USEC, CHUNK_TYPE_UUID, config, hep_chunk_ip4::data, hep_chunk_ip6::data, hep_generic::dst_port, errno, hep_generic::header, hep_ctrl::id, INITIALIZE_GENERIC_HEP_CHUNK, INITIALIZE_GENERIC_HEP_CHUNK_DATA, INITIALIZE_GENERIC_HEP_IDS_VAR, hep_generic::ip_family, hep_generic::ip_proto, hep_ctrl::length, hep_generic::proto_t, RAII_VAR, hep_generic::src_port, hep_generic::time_sec, and hep_generic::time_usec.

Referenced by hepv3_send_packet().

◆ hepv3_config_alloc()

static void* hepv3_config_alloc ( void  )
static

HEPv3 configuration object allocation.

Definition at line 299 of file res_hep.c.

300 {
301  struct hepv3_global_config *config;
302 
304  if (!config || ast_string_field_init(config, 32)) {
305  return NULL;
306  }
307 
308  return config;
309 }
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static void hepv3_config_dtor(void *obj)
Definition: res_hep.c:291
#define NULL
Definition: resample.c:96
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
Global configuration for the module.
Definition: res_hep.c:236

References ao2_alloc, ast_string_field_init, config, hepv3_config_dtor(), and NULL.

Referenced by module_config_alloc().

◆ hepv3_config_dtor()

static void hepv3_config_dtor ( void *  obj)
static

Definition at line 291 of file res_hep.c.

292 {
293  struct hepv3_global_config *config = obj;
294 
296 }
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374

References ast_string_field_free_memory, and config.

Referenced by hepv3_config_alloc().

◆ hepv3_config_post_apply()

static void hepv3_config_post_apply ( void  )
static

Post-apply callback for the config framework.

This will create the run-time information from the supplied configuration.

Definition at line 627 of file res_hep.c.

628 {
630  struct hepv3_runtime_data *data;
631 
632  data = hepv3_data_alloc(mod_cfg->general);
633  if (!data) {
634  return;
635  }
636 
637  ao2_global_obj_replace_unref(global_data, data);
638  ao2_ref(data, -1);
639 }
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
Definition: astobj2.h:901
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
static struct hepv3_runtime_data * hepv3_data_alloc(struct hepv3_global_config *config)
Allocate the HEPv3 run-time data.
Definition: res_hep.c:371

References ao2_cleanup, ao2_global_obj_ref, ao2_global_obj_replace_unref, ao2_ref, hepv3_data_alloc(), and RAII_VAR.

◆ hepv3_config_pre_apply()

static int hepv3_config_pre_apply ( void  )
static

Pre-apply callback for the config framework.

This validates that required fields exist and are populated.

Definition at line 604 of file res_hep.c.

605 {
606  struct module_config *config = aco_pending_config(&cfg_info);
607 
608  if (!config->general->enabled) {
609  /* If we're not enabled, we don't care about anything else */
610  return 0;
611  }
612 
613  if (ast_strlen_zero(config->general->capture_address)) {
614  ast_log(AST_LOG_ERROR, "Missing required configuration option 'capture_address'\n");
615  return -1;
616  }
617 
618  return 0;
619 }
void * aco_pending_config(struct aco_info *info)
Get pending config changes.

References aco_pending_config(), ast_log, AST_LOG_ERROR, ast_strlen_zero(), and config.

◆ hepv3_create_capture_info()

struct hepv3_capture_info* hepv3_create_capture_info ( const void *  payload,
size_t  len 
)

Create a hepv3_capture_info object.

This returned object is an ao2 reference counted object.

Any attribute in the returned hepv3_capture_info that is a pointer should point to something that is allocated on the heap, as it will be free'd when the hepv3_capture_info object is reclaimed.

Parameters
payloadThe payload to send to the HEP capture node
lenLength of payload
Returns
A hepv3_capture_info ref counted object on success
Return values
NULLon error

Definition at line 428 of file res_hep.c.

429 {
430  struct hepv3_capture_info *info;
431 
432  info = ao2_alloc(sizeof(*info), capture_info_dtor);
433  if (!info) {
434  return NULL;
435  }
436 
437  info->payload = ast_malloc(len);
438  if (!info->payload) {
439  ao2_ref(info, -1);
440  return NULL;
441  }
442  memcpy(info->payload, payload, len);
443  info->len = len;
444 
445  /* Set a reasonable default */
446  info->protocol_id = IPPROTO_UDP;
447 
448  return info;
449 }
static void capture_info_dtor(void *obj)
Destructor for a hepv3_capture_info object.
Definition: res_hep.c:401
void * payload
Definition: res_hep.h:66

References ao2_alloc, ao2_ref, ast_malloc, capture_info_dtor(), sip_to_pjsip::info(), len(), NULL, and hepv3_capture_info::payload.

Referenced by logging_on_rx_msg(), logging_on_tx_msg(), and rtcp_message_handler().

◆ hepv3_data_alloc()

static struct hepv3_runtime_data* hepv3_data_alloc ( struct hepv3_global_config config)
static

Allocate the HEPv3 run-time data.

Definition at line 371 of file res_hep.c.

372 {
373  struct hepv3_runtime_data *data;
374 
375  data = ao2_alloc(sizeof(*data), hepv3_data_dtor);
376  if (!data) {
377  return NULL;
378  }
379 
380  data->sockfd = -1;
381 
383  ast_log(AST_LOG_WARNING, "Failed to create address from %s\n", config->capture_address);
384  ao2_ref(data, -1);
385  return NULL;
386 
387  }
388 
389  data->sockfd = socket(ast_sockaddr_is_ipv6(&data->remote_addr) ? AF_INET6 : AF_INET, SOCK_DGRAM, 0);
390  if (data->sockfd < 0) {
391  ast_log(AST_LOG_WARNING, "Failed to create socket for address %s: %s\n",
392  config->capture_address, strerror(errno));
393  ao2_ref(data, -1);
394  return NULL;
395  }
396 
397  return data;
398 }
@ PARSE_PORT_REQUIRE
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.
Definition: netsock2.c:337
@ AST_AF_UNSPEC
Definition: netsock2.h:54
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:524
static void hepv3_data_dtor(void *obj)
HEPv3 run-time data destructor.
Definition: res_hep.c:360
struct ast_sockaddr remote_addr
Definition: res_hep.c:253

References ao2_alloc, ao2_ref, AST_AF_UNSPEC, ast_log, AST_LOG_WARNING, ast_sockaddr_is_ipv6(), ast_sockaddr_resolve_first_af(), config, errno, hepv3_data_dtor(), NULL, PARSE_PORT_REQUIRE, hepv3_runtime_data::remote_addr, and hepv3_runtime_data::sockfd.

Referenced by hepv3_config_post_apply().

◆ hepv3_data_dtor()

static void hepv3_data_dtor ( void *  obj)
static

HEPv3 run-time data destructor.

Definition at line 360 of file res_hep.c.

361 {
362  struct hepv3_runtime_data *data = obj;
363 
364  if (data->sockfd > -1) {
365  close(data->sockfd);
366  data->sockfd = -1;
367  }
368 }

References hepv3_runtime_data::sockfd.

Referenced by hepv3_data_alloc().

◆ hepv3_get_uuid_type()

enum hep_uuid_type hepv3_get_uuid_type ( void  )

Get the preferred UUID type.

Since
13.10.0
Returns
The type of UUID the packet should use

Definition at line 401 of file res_hep.c.

410 {
412 
413  if (!config) {
414  /* Well, that's unfortunate. Return something. */
415  return HEP_UUID_TYPE_CALL_ID;
416  }
417 
418  return config->general->uuid_type;
419 }
@ HEP_UUID_TYPE_CALL_ID
Definition: res_hep.h:53

Referenced by assign_uuid().

◆ hepv3_is_loaded()

int hepv3_is_loaded ( void  )

Return whether or not we're currently loaded and active.

Return values
0The module is not loaded
1The module is loaded

Definition at line 421 of file res_hep.c.

422 {
424 
425  return config && config->general->enabled;
426 }

References ao2_cleanup, ao2_global_obj_ref, config, and RAII_VAR.

Referenced by load_module().

◆ hepv3_send_packet()

int hepv3_send_packet ( struct hepv3_capture_info capture_info)

Send a generic packet capture to HEPv3.

Parameters
capture_infoInformation describing the packet. This should be a reference counted object, created via hepv3_create_capture_info.

Once this function is called, it assumes ownership of the capture_info object and steals the reference of the object. Regardless of success or failure, the calling function should assumed that this function will own the object.

Return values
0on success
-1on error

Definition at line 581 of file res_hep.c.

582 {
584  int res;
585 
586  if (!config || !config->general->enabled) {
587  ao2_ref(capture_info, -1);
588  return 0;
589  }
590 
591  res = ast_taskprocessor_push(hep_queue_tp, hep_queue_cb, capture_info);
592  if (res == -1) {
593  ao2_ref(capture_info, -1);
594  }
595 
596  return res;
597 }
static int hep_queue_cb(void *data)
Callback function for the hep_queue_tp taskprocessor.
Definition: res_hep.c:452
static struct ast_taskprocessor * hep_queue_tp
Definition: res_hep.c:278
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.

References ao2_cleanup, ao2_global_obj_ref, ao2_ref, ast_taskprocessor_push(), config, hep_queue_cb(), hep_queue_tp, and RAII_VAR.

Referenced by logging_on_rx_msg(), logging_on_tx_msg(), and rtcp_message_handler().

◆ load_module()

static int load_module ( void  )
static

Load the module.

Definition at line 669 of file res_hep.c.

670 {
671  if (aco_info_init(&cfg_info)) {
672  goto error;
673  }
674 
676  if (!hep_queue_tp) {
677  goto error;
678  }
679 
680  aco_option_register(&cfg_info, "enabled", ACO_EXACT, global_options, "yes", OPT_BOOL_T, 1, FLDSET(struct hepv3_global_config, enabled));
681  aco_option_register(&cfg_info, "capture_address", ACO_EXACT, global_options, "", OPT_STRINGFIELD_T, 1, STRFLDSET(struct hepv3_global_config, capture_address));
682  aco_option_register(&cfg_info, "capture_password", ACO_EXACT, global_options, "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct hepv3_global_config, capture_password));
683  aco_option_register(&cfg_info, "capture_id", ACO_EXACT, global_options, "0", OPT_UINT_T, 0, STRFLDSET(struct hepv3_global_config, capture_id));
684  aco_option_register_custom(&cfg_info, "uuid_type", ACO_EXACT, global_options, "call-id", uuid_type_handler, 0);
685 
686  if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
687  goto error;
688  }
689 
691 
692 error:
693  aco_info_destroy(&cfg_info);
695 }
@ ACO_EXACT
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.
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.
static int enabled
Definition: dnsmgr.c:91
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
struct aco_type * global_options[]
Definition: res_hep.c:265
static int uuid_type_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Handler for the uuid_type attribute.
Definition: res_hep.c:341
@ TPS_REF_DEFAULT
return a reference to a taskprocessor, create one if it does not exist
Definition: taskprocessor.h:76
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.
int error(const char *format,...)
Definition: utils/frame.c:999

◆ module_config_alloc()

static void * module_config_alloc ( void  )
static

Module config constructor.

Definition at line 322 of file res_hep.c.

323 {
324  struct module_config *config;
325 
327  if (!config) {
328  return NULL;
329  }
330 
331  config->general = hepv3_config_alloc();
332  if (!config->general) {
333  ao2_ref(config, -1);
334  config = NULL;
335  }
336 
337  return config;
338 }
static void * hepv3_config_alloc(void)
HEPv3 configuration object allocation.
Definition: res_hep.c:299
static void module_config_dtor(void *obj)
Configuration object destructor.
Definition: res_hep.c:312

References ao2_alloc, ao2_ref, config, hepv3_config_alloc(), module_config_dtor(), and NULL.

◆ module_config_dtor()

static void module_config_dtor ( void *  obj)
static

Configuration object destructor.

Definition at line 312 of file res_hep.c.

313 {
314  struct module_config *config = obj;
315 
316  if (config->general) {
317  ao2_ref(config->general, -1);
318  }
319 }

References ao2_ref, and config.

Referenced by module_config_alloc().

◆ reload_module()

static int reload_module ( void  )
static

Reload the module.

Definition at line 644 of file res_hep.c.

645 {
646  if (aco_process_config(&cfg_info, 1) == ACO_PROCESS_ERROR) {
647  return -1;
648  }
649  return 0;
650 }

References aco_process_config(), and ACO_PROCESS_ERROR.

◆ unload_module()

static int unload_module ( void  )
static

Unload the module.

Definition at line 655 of file res_hep.c.

656 {
658 
660  ao2_global_obj_release(global_data);
661  aco_info_destroy(&cfg_info);
662 
663  return 0;
664 }
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
Definition: astobj2.h:859
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.

References aco_info_destroy(), ao2_global_obj_release, ast_taskprocessor_unreference(), and hep_queue_tp.

◆ uuid_type_handler()

static int uuid_type_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Handler for the uuid_type attribute.

Definition at line 341 of file res_hep.c.

342 {
343  struct hepv3_global_config *global_config = obj;
344 
345  if (strcasecmp(var->name, "uuid_type")) {
346  return -1;
347  }
348 
349  if (!strcasecmp(var->value, "channel")) {
351  } else if (!strcasecmp(var->value, "call-id")) {
353  } else {
354  return -1;
355  }
356  return 0;
357 }
#define var
Definition: ast_expr2f.c:614
@ HEP_UUID_TYPE_CHANNEL
Definition: res_hep.h:54

References HEP_UUID_TYPE_CALL_ID, HEP_UUID_TYPE_CHANNEL, and var.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "HEPv3 API" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_APP_DEPEND, }
static

Definition at line 669 of file res_hep.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 703 of file res_hep.c.

◆ global_option

struct aco_type global_option
static

Definition at line 1 of file res_hep.c.

◆ global_options

struct aco_type* global_options[] = ACO_TYPES(&global_option)

Definition at line 265 of file res_hep.c.

◆ hep_queue_tp

struct ast_taskprocessor* hep_queue_tp
static

Definition at line 278 of file res_hep.c.

Referenced by hepv3_send_packet(), and unload_module().

◆ hepv3_conf

struct aco_file hepv3_conf
Initial value:
= {
.filename = "hep.conf",
}
#define ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.
static struct aco_type global_option
Definition: res_hep.c:257

Definition at line 265 of file res_hep.c.