Asterisk - The Open Source Telephony Project GIT-master-8924258
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
res_hep.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 1999 - 2014, Digium, Inc.
5 *
6 * Alexandr Dubovikov <alexandr.dubovikov@sipcapture.org>
7 * Matt Jordan <mjordan@digium.com>
8 *
9 * See http://www.asterisk.org for more information about
10 * the Asterisk project. Please do not directly contact
11 * any of the maintainers of this project for assistance;
12 * the project provides a web site, mailing lists and IRC
13 * channels for your use.
14 *
15 * This program is free software, distributed under the terms of
16 * the GNU General Public License Version 2. See the LICENSE file
17 * at the top of the source tree.
18 */
19
20/*!
21 * \file
22 * \brief Routines for integration with Homer using HEPv3
23 *
24 * \author Alexandr Dubovikov <alexandr.dubovikov@sipcapture.org>
25 * \author Matt Jordan <mjordan@digium.com>
26 *
27 */
28
29/*!
30 * \li \ref res_hep.c uses the configuration file \ref hep.conf
31 * \addtogroup configuration_file Configuration Files
32 */
33
34/*!
35 * \page hep.conf hep.conf
36 * \verbinclude hep.conf.sample
37 */
38
39/*** MODULEINFO
40 <support_level>extended</support_level>
41 ***/
42
43/*** DOCUMENTATION
44 <configInfo name="res_hep" language="en_US">
45 <synopsis>Resource for integration with Homer using HEPv3</synopsis>
46 <configFile name="hep.conf">
47 <configObject name="general">
48 <since>
49 <version>12.2.0</version>
50 </since>
51 <synopsis>General settings.</synopsis>
52 <description><para>
53 The <emphasis>general</emphasis> settings section contains information
54 to configure Asterisk as a Homer capture agent.
55 </para>
56 </description>
57 <configOption name="enabled" default="yes">
58 <since>
59 <version>12.2.0</version>
60 </since>
61 <synopsis>Enable or disable packet capturing.</synopsis>
62 <description>
63 <enumlist>
64 <enum name="no" />
65 <enum name="yes" />
66 </enumlist>
67 </description>
68 </configOption>
69 <configOption name="uuid_type" default="call-id">
70 <since>
71 <version>12.2.0</version>
72 </since>
73 <synopsis>The preferred type of UUID to pass to Homer.</synopsis>
74 <description>
75 <enumlist>
76 <enum name="call-id"><para>Use the PJSIP Call-Id</para></enum>
77 <enum name="channel"><para>Use the Asterisk channel name</para></enum>
78 </enumlist>
79 </description>
80 </configOption>
81 <configOption name="capture_address">
82 <since>
83 <version>13.16.0</version>
84 <version>14.5.0</version>
85 </since>
86 <synopsis>The address and port of the Homer server to send packets to.</synopsis>
87 </configOption>
88 <configOption name="capture_password">
89 <since>
90 <version>12.2.0</version>
91 </since>
92 <synopsis>If set, the authentication password to send to Homer.</synopsis>
93 </configOption>
94 <configOption name="capture_id" default="0">
95 <since>
96 <version>12.2.0</version>
97 </since>
98 <synopsis>The ID for this capture agent.</synopsis>
99 </configOption>
100 <configOption name="capture_name" default="">
101 <since>
102 <version>18.16.0</version>
103 <version>20.1.0</version>
104 </since>
105 <synopsis>The name for this capture agent.</synopsis>
106 </configOption>
107 </configObject>
108 </configFile>
109 </configInfo>
110***/
111
112#include "asterisk.h"
113
114#include "asterisk/module.h"
115#include "asterisk/astobj2.h"
118#include "asterisk/res_hep.h"
119
120#include <netinet/ip.h>
121#include <netinet/tcp.h>
122#include <netinet/udp.h>
123#include <netinet/ip6.h>
124
125/*! Generic vendor ID. Used for HEPv3 standard packets */
126#define GENERIC_VENDOR_ID 0x0000
127
128/*! Asterisk vendor ID. Used for custom data to send to a capture node */
129#define ASTERISK_VENDOR_ID 0x0004
130
131/*! Chunk types from the HEPv3 Spec */
133
134 /*! THE IP PROTOCOL FAMILY */
136
137 /*! THE IP PROTOCOL ID (UDP, TCP, ETC.) */
139
140 /*! IF IPV4, THE SOURCE ADDRESS */
142
143 /*! IF IPV4, THE DESTINATION ADDRESS */
145
146 /*! IF IPV6, THE SOURCE ADDRESS */
148
149 /*! IF IPV6, THE DESTINATION ADDRESS */
151
152 /*! THE SOURCE PORT */
154
155 /*! THE DESTINATION PORT */
157
158 /*! THE CAPTURE TIME (SECONDS) */
160
161 /*! THE CAPTURE TIME (MICROSECONDS) */
163
164 /*! THE PROTOCOL PACKET TYPE. SEE /REF HEPV3_CAPTURE_TYPE */
166
167 /*! OUR CAPTURE AGENT ID */
169
170 /*! A KEEP ALIVE TIMER */
172
173 /*! THE CAPTURE_PASSWORD IF DEFINED */
175
176 /*! THE ONE AND ONLY PAYLOAD */
178
179 /*! THE ONE AND ONLY (ZIPPED) PAYLOAD */
181
182 /*! THE UUID FOR THIS PACKET */
184
185 /*! THE CAPTURE AGENT NAME */
187};
188
189#define INITIALIZE_GENERIC_HEP_IDS(hep_chunk, type) do { \
190 (hep_chunk)->vendor_id = htons(GENERIC_VENDOR_ID); \
191 (hep_chunk)->type_id = htons((type)); \
192 } while (0)
193
194#define INITIALIZE_GENERIC_HEP_IDS_VAR(hep_chunk, type, len) do { \
195 INITIALIZE_GENERIC_HEP_IDS((hep_chunk), (type)); \
196 (hep_chunk)->length = htons(sizeof(*(hep_chunk)) + len); \
197 } while (0)
198
199#define INITIALIZE_GENERIC_HEP_CHUNK(hep_item, type) do { \
200 INITIALIZE_GENERIC_HEP_IDS(&(hep_item)->chunk, (type)); \
201 (hep_item)->chunk.length = htons(sizeof(*(hep_item))); \
202 } while (0)
203
204#define INITIALIZE_GENERIC_HEP_CHUNK_DATA(hep_item, type, value) do { \
205 INITIALIZE_GENERIC_HEP_CHUNK((hep_item), (type)); \
206 (hep_item)->data = (value); \
207 } while (0)
208
209/*
210 * HEPv3 Types.
211 * Note that the content in these is stored in network byte order.
212 */
213
214struct hep_chunk {
218} __attribute__((packed));
219
223} __attribute__((packed));
224
228} __attribute__((packed));
229
233} __attribute__((packed));
234
237 struct in_addr data;
238} __attribute__((packed));
239
242 struct in6_addr data;
243} __attribute__((packed));
244
245struct hep_ctrl {
246 char id[4];
248} __attribute__((packed));
249
250/* HEP structures */
251
262} __attribute__((packed));
263
264/*! \brief Global configuration for the module */
266 unsigned int enabled; /*!< Whether or not sending is enabled */
267 unsigned int capture_id; /*!< Capture ID for this agent */
268 enum hep_uuid_type uuid_type; /*!< The preferred type of the UUID */
270 AST_STRING_FIELD(capture_address); /*!< Address to send to */
271 AST_STRING_FIELD(capture_password); /*!< Password for Homer server */
272 AST_STRING_FIELD(capture_name); /*!< Capture name for this agent */
273 );
274};
275
276/*! \brief The actual module config */
277struct module_config {
278 struct hepv3_global_config *general; /*!< The general config settings */
279};
280
281/*! \brief Run-time data derived from \ref hepv3_global_config */
283 struct ast_sockaddr remote_addr; /*!< The address to send to */
284 int sockfd; /*!< The socket file descriptor */
285};
286
287static struct aco_type global_option = {
288 .type = ACO_GLOBAL,
289 .name = "general",
290 .item_offset = offsetof(struct module_config, general),
291 .category_match = ACO_WHITELIST_EXACT,
292 .category = "general",
293};
294
296
298 .filename = "hep.conf",
299 .types = ACO_TYPES(&global_option),
300};
301
302/*! \brief The module configuration container */
304
305/*! \brief Current module data */
306static AO2_GLOBAL_OBJ_STATIC(global_data);
307
309
310static void *module_config_alloc(void);
311static int hepv3_config_pre_apply(void);
312static void hepv3_config_post_apply(void);
313
314/*! \brief Register information about the configs being processed by this module */
316 .files = ACO_FILES(&hepv3_conf),
317 .pre_apply_config = hepv3_config_pre_apply,
318 .post_apply_config = hepv3_config_post_apply,
319);
320
321static void hepv3_config_dtor(void *obj)
322{
323 struct hepv3_global_config *config = obj;
324
326}
327
328/*! \brief HEPv3 configuration object allocation */
329static void *hepv3_config_alloc(void)
330{
332
334 if (!config || ast_string_field_init(config, 32)) {
335 return NULL;
336 }
337
338 return config;
339}
340
341/*! \brief Configuration object destructor */
342static void module_config_dtor(void *obj)
343{
344 struct module_config *config = obj;
345
346 if (config->general) {
347 ao2_ref(config->general, -1);
348 }
349}
350
351/*! \brief Module config constructor */
352static void *module_config_alloc(void)
353{
354 struct module_config *config;
355
357 if (!config) {
358 return NULL;
359 }
360
361 config->general = hepv3_config_alloc();
362 if (!config->general) {
363 ao2_ref(config, -1);
364 config = NULL;
365 }
366
367 return config;
368}
369
370/*! \brief Handler for the uuid_type attribute */
371static int uuid_type_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
372{
374
375 if (strcasecmp(var->name, "uuid_type")) {
376 return -1;
377 }
378
379 if (!strcasecmp(var->value, "channel")) {
381 } else if (!strcasecmp(var->value, "call-id")) {
383 } else {
384 return -1;
385 }
386 return 0;
387}
388
389/*! \brief HEPv3 run-time data destructor */
390static void hepv3_data_dtor(void *obj)
391{
392 struct hepv3_runtime_data *data = obj;
393
394 if (data->sockfd > -1) {
395 close(data->sockfd);
396 data->sockfd = -1;
397 }
398}
399
400/*! \brief Allocate the HEPv3 run-time data */
402{
403 struct hepv3_runtime_data *data;
404
405 data = ao2_alloc(sizeof(*data), hepv3_data_dtor);
406 if (!data) {
407 return NULL;
408 }
409
410 data->sockfd = -1;
411
413 ast_log(AST_LOG_WARNING, "Failed to create address from %s\n", config->capture_address);
414 ao2_ref(data, -1);
415 return NULL;
416
417 }
418
419 data->sockfd = socket(ast_sockaddr_is_ipv6(&data->remote_addr) ? AF_INET6 : AF_INET, SOCK_DGRAM, 0);
420 if (data->sockfd < 0) {
421 ast_log(AST_LOG_WARNING, "Failed to create socket for address %s: %s\n",
422 config->capture_address, strerror(errno));
423 ao2_ref(data, -1);
424 return NULL;
425 }
426
427 return data;
428}
429
430/*! \brief Destructor for a \ref hepv3_capture_info object */
431static void capture_info_dtor(void *obj)
432{
433 struct hepv3_capture_info *info = obj;
434
435 ast_free(info->uuid);
436 ast_free(info->payload);
437}
438
440{
442
443 if (!config) {
444 /* Well, that's unfortunate. Return something. */
446 }
447
448 return config->general->uuid_type;
449}
450
452{
454
455 return config && config->general->enabled;
456}
457
459{
460 struct hepv3_capture_info *info;
461
463 if (!info) {
464 return NULL;
465 }
466
467 info->payload = ast_malloc(len);
468 if (!info->payload) {
469 ao2_ref(info, -1);
470 return NULL;
471 }
472 memcpy(info->payload, payload, len);
473 info->len = len;
474
475 /* Set a reasonable default */
476 info->protocol_id = IPPROTO_UDP;
477
478 return info;
479}
480
481/*! \brief Callback function for the \ref hep_queue_tp taskprocessor */
482static int hep_queue_cb(void *data)
483{
485 RAII_VAR(struct hepv3_runtime_data *, hepv3_data, ao2_global_obj_ref(global_data), ao2_cleanup);
486 RAII_VAR(struct hepv3_capture_info *, capture_info, data, ao2_cleanup);
487 struct hep_generic hg_pkt;
488 unsigned int packet_len = 0, sock_buffer_len;
489 struct hep_chunk_ip4 ipv4_src, ipv4_dst;
490 struct hep_chunk_ip6 ipv6_src, ipv6_dst;
491 struct hep_chunk auth_key, payload, uuid, capturename;
492 void *sock_buffer;
493 int res;
494
495 if (!capture_info || !config || !hepv3_data) {
496 return 0;
497 }
498
499 if (ast_sockaddr_is_ipv4(&capture_info->src_addr) != ast_sockaddr_is_ipv4(&capture_info->dst_addr)) {
500 ast_log(AST_LOG_NOTICE, "Unable to send packet: Address Family mismatch between source/destination\n");
501 return -1;
502 }
503
504 packet_len = sizeof(hg_pkt);
505
506 /* Build HEPv3 header, capture info, and calculate the total packet size */
507 memcpy(hg_pkt.header.id, "\x48\x45\x50\x33", 4);
508
509 INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.ip_proto, CHUNK_TYPE_IP_PROTOCOL_ID, capture_info->protocol_id);
510 INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.src_port, CHUNK_TYPE_SRC_PORT, htons(ast_sockaddr_port(&capture_info->src_addr)));
511 INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.dst_port, CHUNK_TYPE_DST_PORT, htons(ast_sockaddr_port(&capture_info->dst_addr)));
512 INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.time_sec, CHUNK_TYPE_TIMESTAMP_SEC, htonl(capture_info->capture_time.tv_sec));
513 INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.time_usec, CHUNK_TYPE_TIMESTAMP_USEC, htonl(capture_info->capture_time.tv_usec));
514 INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.proto_t, CHUNK_TYPE_PROTOCOL_TYPE, capture_info->capture_type);
516
517 if (ast_sockaddr_is_ipv4(&capture_info->src_addr)) {
520
522 inet_pton(AF_INET, ast_sockaddr_stringify_addr(&capture_info->src_addr), &ipv4_src.data);
523
525 inet_pton(AF_INET, ast_sockaddr_stringify_addr(&capture_info->dst_addr), &ipv4_dst.data);
526
527 packet_len += (sizeof(ipv4_src) + sizeof(ipv4_dst));
528 } else {
531
533 inet_pton(AF_INET6, ast_sockaddr_stringify_addr(&capture_info->src_addr), &ipv6_src.data);
534
536 inet_pton(AF_INET6, ast_sockaddr_stringify_addr(&capture_info->dst_addr), &ipv6_dst.data);
537
538 packet_len += (sizeof(ipv6_src) + sizeof(ipv6_dst));
539 }
540
541 if (!ast_strlen_zero(config->general->capture_password)) {
542 INITIALIZE_GENERIC_HEP_IDS_VAR(&auth_key, CHUNK_TYPE_AUTH_KEY, strlen(config->general->capture_password));
543 packet_len += (sizeof(auth_key) + strlen(config->general->capture_password));
544 }
545 if (!ast_strlen_zero(config->general->capture_name)) {
546 INITIALIZE_GENERIC_HEP_IDS_VAR(&capturename, CHUNK_TYPE_CAPTURE_AGENT_NAME, strlen(config->general->capture_name));
547 packet_len += (sizeof(capturename) + strlen(config->general->capture_name));
548 }
549 INITIALIZE_GENERIC_HEP_IDS_VAR(&uuid, CHUNK_TYPE_UUID, strlen(capture_info->uuid));
550 packet_len += (sizeof(uuid) + strlen(capture_info->uuid));
552 capture_info->zipped ? CHUNK_TYPE_PAYLOAD_ZIP : CHUNK_TYPE_PAYLOAD, capture_info->len);
553 packet_len += (sizeof(payload) + capture_info->len);
554 hg_pkt.header.length = htons(packet_len);
555
556 /* Build the buffer to send */
557 sock_buffer = ast_malloc(packet_len);
558 if (!sock_buffer) {
559 return -1;
560 }
561
562 /* Copy in the header */
563 memcpy(sock_buffer, &hg_pkt, sizeof(hg_pkt));
564 sock_buffer_len = sizeof(hg_pkt);
565
566 /* Addresses */
567 if (ast_sockaddr_is_ipv4(&capture_info->src_addr)) {
568 memcpy(sock_buffer + sock_buffer_len, &ipv4_src, sizeof(ipv4_src));
569 sock_buffer_len += sizeof(ipv4_src);
570 memcpy(sock_buffer + sock_buffer_len, &ipv4_dst, sizeof(ipv4_dst));
571 sock_buffer_len += sizeof(ipv4_dst);
572 } else {
573 memcpy(sock_buffer + sock_buffer_len, &ipv6_src, sizeof(ipv6_src));
574 sock_buffer_len += sizeof(ipv6_src);
575 memcpy(sock_buffer + sock_buffer_len, &ipv6_dst, sizeof(ipv6_dst));
576 sock_buffer_len += sizeof(ipv6_dst);
577 }
578
579 /* Auth Key */
580 if (!ast_strlen_zero(config->general->capture_password)) {
581 memcpy(sock_buffer + sock_buffer_len, &auth_key, sizeof(auth_key));
582 sock_buffer_len += sizeof(auth_key);
583 memcpy(sock_buffer + sock_buffer_len, config->general->capture_password, strlen(config->general->capture_password));
584 sock_buffer_len += strlen(config->general->capture_password);
585 }
586
587 /* UUID */
588 memcpy(sock_buffer + sock_buffer_len, &uuid, sizeof(uuid));
589 sock_buffer_len += sizeof(uuid);
590 memcpy(sock_buffer + sock_buffer_len, capture_info->uuid, strlen(capture_info->uuid));
591 sock_buffer_len += strlen(capture_info->uuid);
592
593 /* Capture Agent Name */
594 if (!ast_strlen_zero(config->general->capture_name)) {
595 memcpy(sock_buffer + sock_buffer_len, &capturename, sizeof(capturename));
596 sock_buffer_len += sizeof(capturename);
597 memcpy(sock_buffer + sock_buffer_len, config->general->capture_name, strlen(config->general->capture_name));
598 sock_buffer_len += strlen(config->general->capture_name);
599 }
600
601 /* Packet! */
602 memcpy(sock_buffer + sock_buffer_len, &payload, sizeof(payload));
603 sock_buffer_len += sizeof(payload);
604 memcpy(sock_buffer + sock_buffer_len, capture_info->payload, capture_info->len);
605 sock_buffer_len += capture_info->len;
606
607 ast_assert(sock_buffer_len == packet_len);
608
609 res = ast_sendto(hepv3_data->sockfd, sock_buffer, sock_buffer_len, 0, &hepv3_data->remote_addr);
610 if (res < 0) {
611 ast_log(AST_LOG_ERROR, "Error [%d] while sending packet to HEPv3 server: %s\n",
612 errno, strerror(errno));
613 } else if (res != sock_buffer_len) {
614 ast_log(AST_LOG_WARNING, "Failed to send complete packet to HEPv3 server: %d of %u sent\n",
615 res, sock_buffer_len);
616 res = -1;
617 }
618
619 ast_free(sock_buffer);
620 return res;
621}
622
623int hepv3_send_packet(struct hepv3_capture_info *capture_info)
624{
626 int res;
627
628 if (!config || !config->general->enabled) {
629 ao2_ref(capture_info, -1);
630 return 0;
631 }
632
634 if (res == -1) {
635 ao2_ref(capture_info, -1);
636 }
637
638 return res;
639}
640
641/*!
642 * \brief Pre-apply callback for the config framework.
643 *
644 * This validates that required fields exist and are populated.
645 */
647{
648 struct module_config *config = aco_pending_config(&cfg_info);
649
650 if (!config->general->enabled) {
651 /* If we're not enabled, we don't care about anything else */
652 return 0;
653 }
654
655 if (ast_strlen_zero(config->general->capture_address)) {
656 ast_log(AST_LOG_ERROR, "Missing required configuration option 'capture_address'\n");
657 return -1;
658 }
659
660 return 0;
661}
662
663/*!
664 * \brief Post-apply callback for the config framework.
665 *
666 * This will create the run-time information from the supplied
667 * configuration.
668 */
669static void hepv3_config_post_apply(void)
670{
672 struct hepv3_runtime_data *data;
673
674 data = hepv3_data_alloc(mod_cfg->general);
675 if (!data) {
676 return;
677 }
678
679 ao2_global_obj_replace_unref(global_data, data);
680 ao2_ref(data, -1);
681}
682
683/*!
684 * \brief Reload the module
685 */
686static int reload_module(void)
687{
688 if (aco_process_config(&cfg_info, 1) == ACO_PROCESS_ERROR) {
689 return -1;
690 }
691 return 0;
692}
693
694/*!
695 * \brief Unload the module
696 */
697static int unload_module(void)
698{
700
702 ao2_global_obj_release(global_data);
703 aco_info_destroy(&cfg_info);
704
705 return 0;
706}
707
708/*!
709 * \brief Load the module
710 */
711static int load_module(void)
712{
713 if (aco_info_init(&cfg_info)) {
714 goto error;
715 }
716
718 if (!hep_queue_tp) {
719 goto error;
720 }
721
722 aco_option_register(&cfg_info, "enabled", ACO_EXACT, global_options, "yes", OPT_BOOL_T, 1, FLDSET(struct hepv3_global_config, enabled));
723 aco_option_register(&cfg_info, "capture_address", ACO_EXACT, global_options, "", OPT_STRINGFIELD_T, 1, STRFLDSET(struct hepv3_global_config, capture_address));
724 aco_option_register(&cfg_info, "capture_password", ACO_EXACT, global_options, "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct hepv3_global_config, capture_password));
725 aco_option_register(&cfg_info, "capture_id", ACO_EXACT, global_options, "0", OPT_UINT_T, 0, STRFLDSET(struct hepv3_global_config, capture_id));
726 aco_option_register(&cfg_info, "capture_name", ACO_EXACT, global_options, "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct hepv3_global_config, capture_name));
727 aco_option_register_custom(&cfg_info, "uuid_type", ACO_EXACT, global_options, "call-id", uuid_type_handler, 0);
728
729 if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
730 goto error;
731 }
732
734
735error:
736 aco_info_destroy(&cfg_info);
738}
739
741 .support_level = AST_MODULE_SUPPORT_EXTENDED,
742 .load = load_module,
743 .unload = unload_module,
745 .load_pri = AST_MODPRI_APP_DEPEND,
#define var
Definition: ast_expr2f.c:605
Asterisk main include file. File version handling, generic pbx functions.
#define ast_free(a)
Definition: astmm.h:180
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define ast_log
Definition: astobj2.c:42
#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_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
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
Definition: astobj2.h:859
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static const char config[]
Definition: chan_ooh323.c:111
Configuration option-handling.
@ 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.
#define ACO_FILES(...)
@ 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.
@ ACO_GLOBAL
@ ACO_WHITELIST_EXACT
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 enabled
Definition: dnsmgr.c:91
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)
Definition: func_uuid.c:52
@ PARSE_PORT_REQUIRE
#define AST_LOG_WARNING
#define AST_LOG_ERROR
#define AST_LOG_NOTICE
int errno
Asterisk module definitions.
@ AST_MODFLAG_LOAD_ORDER
Definition: module.h:331
@ AST_MODFLAG_GLOBAL_SYMBOLS
Definition: module.h:330
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:557
@ AST_MODPRI_APP_DEPEND
Definition: module.h:342
@ AST_MODULE_SUPPORT_EXTENDED
Definition: module.h:122
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
@ 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
def info(msg)
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
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:517
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:524
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
@ AST_AF_UNSPEC
Definition: netsock2.h:54
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
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
Definition: netsock2.c:497
static int reload(void)
struct aco_type * global_options[]
Definition: res_hep.c:295
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:371
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.
hepv3_chunk_types
Definition: res_hep.c:132
@ CHUNK_TYPE_TIMESTAMP_USEC
Definition: res_hep.c:162
@ CHUNK_TYPE_PAYLOAD_ZIP
Definition: res_hep.c:180
@ CHUNK_TYPE_IPV4_DST_ADDR
Definition: res_hep.c:144
@ CHUNK_TYPE_IPV6_SRC_ADDR
Definition: res_hep.c:147
@ CHUNK_TYPE_IP_PROTOCOL_ID
Definition: res_hep.c:138
@ CHUNK_TYPE_DST_PORT
Definition: res_hep.c:156
@ CHUNK_TYPE_TIMESTAMP_SEC
Definition: res_hep.c:159
@ CHUNK_TYPE_PROTOCOL_TYPE
Definition: res_hep.c:165
@ CHUNK_TYPE_PAYLOAD
Definition: res_hep.c:177
@ CHUNK_TYPE_IPV4_SRC_ADDR
Definition: res_hep.c:141
@ CHUNK_TYPE_CAPTURE_AGENT_NAME
Definition: res_hep.c:186
@ CHUNK_TYPE_IPV6_DST_ADDR
Definition: res_hep.c:150
@ CHUNK_TYPE_AUTH_KEY
Definition: res_hep.c:174
@ CHUNK_TYPE_IP_PROTOCOL_FAMILY
Definition: res_hep.c:135
@ CHUNK_TYPE_UUID
Definition: res_hep.c:183
@ CHUNK_TYPE_SRC_PORT
Definition: res_hep.c:153
@ CHUNK_TYPE_KEEP_ALIVE_TIMER
Definition: res_hep.c:171
@ CHUNK_TYPE_CAPTURE_AGENT_ID
Definition: res_hep.c:168
static int hep_queue_cb(void *data)
Callback function for the hep_queue_tp taskprocessor.
Definition: res_hep.c:482
enum hep_uuid_type hepv3_get_uuid_type(void)
Get the preferred UUID type.
Definition: res_hep.c:439
#define INITIALIZE_GENERIC_HEP_CHUNK_DATA(hep_item, type, value)
Definition: res_hep.c:204
static struct ast_taskprocessor * hep_queue_tp
Definition: res_hep.c:308
static void * hepv3_config_alloc(void)
HEPv3 configuration object allocation.
Definition: res_hep.c:329
static struct hepv3_runtime_data * hepv3_data_alloc(struct hepv3_global_config *config)
Allocate the HEPv3 run-time data.
Definition: res_hep.c:401
int hepv3_is_loaded(void)
Return whether or not we're currently loaded and active.
Definition: res_hep.c:451
static AO2_GLOBAL_OBJ_STATIC(global_config)
The module configuration container.
static int reload_module(void)
Reload the module.
Definition: res_hep.c:686
static void hepv3_config_post_apply(void)
Post-apply callback for the config framework.
Definition: res_hep.c:669
struct aco_file hepv3_conf
Definition: res_hep.c:297
static void capture_info_dtor(void *obj)
Destructor for a hepv3_capture_info object.
Definition: res_hep.c:431
struct hepv3_capture_info * hepv3_create_capture_info(const void *payload, size_t len)
Create a hepv3_capture_info object.
Definition: res_hep.c:458
static void module_config_dtor(void *obj)
Configuration object destructor.
Definition: res_hep.c:342
static int hepv3_config_pre_apply(void)
Pre-apply callback for the config framework.
Definition: res_hep.c:646
#define INITIALIZE_GENERIC_HEP_CHUNK(hep_item, type)
Definition: res_hep.c:199
static int load_module(void)
Load the module.
Definition: res_hep.c:711
int hepv3_send_packet(struct hepv3_capture_info *capture_info)
Send a generic packet capture to HEPv3.
Definition: res_hep.c:623
static int unload_module(void)
Unload the module.
Definition: res_hep.c:697
#define INITIALIZE_GENERIC_HEP_IDS_VAR(hep_chunk, type, len)
Definition: res_hep.c:194
static void hepv3_config_dtor(void *obj)
Definition: res_hep.c:321
static void * module_config_alloc(void)
Module config constructor.
Definition: res_hep.c:352
static void hepv3_data_dtor(void *obj)
HEPv3 run-time data destructor.
Definition: res_hep.c:390
static struct aco_type global_option
Definition: res_hep.c:287
Routines for integration with Homer using HEPv3.
hep_uuid_type
Definition: res_hep.h:51
@ HEP_UUID_TYPE_CHANNEL
Definition: res_hep.h:53
@ HEP_UUID_TYPE_CALL_ID
Definition: res_hep.h:52
#define NULL
Definition: resample.c:96
unsigned int u_int32_t
unsigned short u_int16_t
unsigned char u_int8_t
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
Definition: stringfields.h:341
#define AST_STRING_FIELD(name)
Declare a string field.
Definition: stringfields.h:303
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
The representation of a single configuration file to be processed.
const char * filename
Type information about a category-level configurable object.
enum aco_type_t type
Socket address structure.
Definition: netsock2.h:97
A ast_taskprocessor structure is a singleton by name.
Definition: taskprocessor.c:69
Structure for variables, used for configurations and for channel variables.
struct hep_chunk chunk
Definition: res_hep.c:236
struct in_addr data
Definition: res_hep.c:237
struct in6_addr data
Definition: res_hep.c:242
struct hep_chunk chunk
Definition: res_hep.c:241
struct hep_chunk chunk
Definition: res_hep.c:226
u_int16_t data
Definition: res_hep.c:227
u_int32_t data
Definition: res_hep.c:232
struct hep_chunk chunk
Definition: res_hep.c:231
struct hep_chunk chunk
Definition: res_hep.c:221
u_int8_t data
Definition: res_hep.c:222
u_int16_t type_id
Definition: res_hep.c:216
u_int16_t length
Definition: res_hep.c:217
u_int16_t vendor_id
Definition: res_hep.c:215
u_int16_t length
Definition: res_hep.c:247
char id[4]
Definition: res_hep.c:246
struct hep_chunk_uint8 ip_proto
Definition: res_hep.c:255
struct hep_ctrl header
Definition: res_hep.c:253
struct hep_chunk_uint8 proto_t
Definition: res_hep.c:260
struct hep_chunk_uint16 dst_port
Definition: res_hep.c:257
struct hep_chunk_uint32 capt_id
Definition: res_hep.c:261
struct hep_chunk_uint32 time_sec
Definition: res_hep.c:258
struct hep_chunk_uint8 ip_family
Definition: res_hep.c:254
struct hep_chunk_uint16 src_port
Definition: res_hep.c:256
struct hep_chunk_uint32 time_usec
Definition: res_hep.c:259
HEPv3 Capture Info.
Definition: res_hep.h:57
void * payload
Definition: res_hep.h:65
Global configuration for the module.
Definition: res_hep.c:265
const ast_string_field capture_password
Definition: res_hep.c:273
unsigned int capture_id
Definition: res_hep.c:267
enum hep_uuid_type uuid_type
Definition: res_hep.c:268
unsigned int enabled
Definition: res_hep.c:266
const ast_string_field capture_name
Definition: res_hep.c:273
const ast_string_field capture_address
Definition: res_hep.c:273
Run-time data derived from hepv3_global_config.
Definition: res_hep.c:282
struct ast_sockaddr remote_addr
Definition: res_hep.c:283
The configuration settings for this module.
Definition: cdr.c:318
struct hepv3_global_config * general
Definition: res_hep.c:278
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
Definition: taskprocessor.h:76
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,...)
Definition: utils/frame.c:999
#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:941
#define ast_assert(a)
Definition: utils.h:739