Asterisk - The Open Source Telephony Project GIT-master-f36a736
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 <synopsis>General settings.</synopsis>
49 <description><para>
50 The <emphasis>general</emphasis> settings section contains information
51 to configure Asterisk as a Homer capture agent.
52 </para>
53 </description>
54 <configOption name="enabled" default="yes">
55 <synopsis>Enable or disable packet capturing.</synopsis>
56 <description>
57 <enumlist>
58 <enum name="no" />
59 <enum name="yes" />
60 </enumlist>
61 </description>
62 </configOption>
63 <configOption name="uuid_type" default="call-id">
64 <synopsis>The preferred type of UUID to pass to Homer.</synopsis>
65 <description>
66 <enumlist>
67 <enum name="call-id"><para>Use the PJSIP Call-Id</para></enum>
68 <enum name="channel"><para>Use the Asterisk channel name</para></enum>
69 </enumlist>
70 </description>
71 </configOption>
72 <configOption name="capture_address">
73 <synopsis>The address and port of the Homer server to send packets to.</synopsis>
74 </configOption>
75 <configOption name="capture_password">
76 <synopsis>If set, the authentication password to send to Homer.</synopsis>
77 </configOption>
78 <configOption name="capture_id" default="0">
79 <synopsis>The ID for this capture agent.</synopsis>
80 </configOption>
81 <configOption name="capture_name" default="">
82 <synopsis>The name for this capture agent.</synopsis>
83 </configOption>
84 </configObject>
85 </configFile>
86 </configInfo>
87***/
88
89#include "asterisk.h"
90
91#include "asterisk/module.h"
92#include "asterisk/astobj2.h"
95#include "asterisk/res_hep.h"
96
97#include <netinet/ip.h>
98#include <netinet/tcp.h>
99#include <netinet/udp.h>
100#include <netinet/ip6.h>
101
102/*! Generic vendor ID. Used for HEPv3 standard packets */
103#define GENERIC_VENDOR_ID 0x0000
104
105/*! Asterisk vendor ID. Used for custom data to send to a capture node */
106#define ASTERISK_VENDOR_ID 0x0004
107
108/*! Chunk types from the HEPv3 Spec */
110
111 /*! THE IP PROTOCOL FAMILY */
113
114 /*! THE IP PROTOCOL ID (UDP, TCP, ETC.) */
116
117 /*! IF IPV4, THE SOURCE ADDRESS */
119
120 /*! IF IPV4, THE DESTINATION ADDRESS */
122
123 /*! IF IPV6, THE SOURCE ADDRESS */
125
126 /*! IF IPV6, THE DESTINATION ADDRESS */
128
129 /*! THE SOURCE PORT */
131
132 /*! THE DESTINATION PORT */
134
135 /*! THE CAPTURE TIME (SECONDS) */
137
138 /*! THE CAPTURE TIME (MICROSECONDS) */
140
141 /*! THE PROTOCOL PACKET TYPE. SEE /REF HEPV3_CAPTURE_TYPE */
143
144 /*! OUR CAPTURE AGENT ID */
146
147 /*! A KEEP ALIVE TIMER */
149
150 /*! THE CAPTURE_PASSWORD IF DEFINED */
152
153 /*! THE ONE AND ONLY PAYLOAD */
155
156 /*! THE ONE AND ONLY (ZIPPED) PAYLOAD */
158
159 /*! THE UUID FOR THIS PACKET */
161
162 /*! THE CAPTURE AGENT NAME */
164};
165
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)); \
169 } while (0)
170
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); \
174 } while (0)
175
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))); \
179 } while (0)
180
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); \
184 } while (0)
185
186/*
187 * HEPv3 Types.
188 * Note that the content in these is stored in network byte order.
189 */
190
191struct hep_chunk {
195} __attribute__((packed));
196
200} __attribute__((packed));
201
205} __attribute__((packed));
206
210} __attribute__((packed));
211
214 struct in_addr data;
215} __attribute__((packed));
216
219 struct in6_addr data;
220} __attribute__((packed));
221
222struct hep_ctrl {
223 char id[4];
225} __attribute__((packed));
226
227/* HEP structures */
228
239} __attribute__((packed));
240
241/*! \brief Global configuration for the module */
243 unsigned int enabled; /*!< Whether or not sending is enabled */
244 unsigned int capture_id; /*!< Capture ID for this agent */
245 enum hep_uuid_type uuid_type; /*!< The preferred type of the UUID */
247 AST_STRING_FIELD(capture_address); /*!< Address to send to */
248 AST_STRING_FIELD(capture_password); /*!< Password for Homer server */
249 AST_STRING_FIELD(capture_name); /*!< Capture name for this agent */
250 );
251};
252
253/*! \brief The actual module config */
254struct module_config {
255 struct hepv3_global_config *general; /*!< The general config settings */
256};
257
258/*! \brief Run-time data derived from \ref hepv3_global_config */
260 struct ast_sockaddr remote_addr; /*!< The address to send to */
261 int sockfd; /*!< The socket file descriptor */
262};
263
264static struct aco_type global_option = {
265 .type = ACO_GLOBAL,
266 .name = "general",
267 .item_offset = offsetof(struct module_config, general),
268 .category_match = ACO_WHITELIST_EXACT,
269 .category = "general",
270};
271
273
275 .filename = "hep.conf",
276 .types = ACO_TYPES(&global_option),
277};
278
279/*! \brief The module configuration container */
281
282/*! \brief Current module data */
283static AO2_GLOBAL_OBJ_STATIC(global_data);
284
286
287static void *module_config_alloc(void);
288static int hepv3_config_pre_apply(void);
289static void hepv3_config_post_apply(void);
290
291/*! \brief Register information about the configs being processed by this module */
293 .files = ACO_FILES(&hepv3_conf),
294 .pre_apply_config = hepv3_config_pre_apply,
295 .post_apply_config = hepv3_config_post_apply,
296);
297
298static void hepv3_config_dtor(void *obj)
299{
300 struct hepv3_global_config *config = obj;
301
303}
304
305/*! \brief HEPv3 configuration object allocation */
306static void *hepv3_config_alloc(void)
307{
309
311 if (!config || ast_string_field_init(config, 32)) {
312 return NULL;
313 }
314
315 return config;
316}
317
318/*! \brief Configuration object destructor */
319static void module_config_dtor(void *obj)
320{
321 struct module_config *config = obj;
322
323 if (config->general) {
324 ao2_ref(config->general, -1);
325 }
326}
327
328/*! \brief Module config constructor */
329static void *module_config_alloc(void)
330{
331 struct module_config *config;
332
334 if (!config) {
335 return NULL;
336 }
337
338 config->general = hepv3_config_alloc();
339 if (!config->general) {
340 ao2_ref(config, -1);
341 config = NULL;
342 }
343
344 return config;
345}
346
347/*! \brief Handler for the uuid_type attribute */
348static int uuid_type_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
349{
351
352 if (strcasecmp(var->name, "uuid_type")) {
353 return -1;
354 }
355
356 if (!strcasecmp(var->value, "channel")) {
358 } else if (!strcasecmp(var->value, "call-id")) {
360 } else {
361 return -1;
362 }
363 return 0;
364}
365
366/*! \brief HEPv3 run-time data destructor */
367static void hepv3_data_dtor(void *obj)
368{
369 struct hepv3_runtime_data *data = obj;
370
371 if (data->sockfd > -1) {
372 close(data->sockfd);
373 data->sockfd = -1;
374 }
375}
376
377/*! \brief Allocate the HEPv3 run-time data */
379{
380 struct hepv3_runtime_data *data;
381
382 data = ao2_alloc(sizeof(*data), hepv3_data_dtor);
383 if (!data) {
384 return NULL;
385 }
386
387 data->sockfd = -1;
388
390 ast_log(AST_LOG_WARNING, "Failed to create address from %s\n", config->capture_address);
391 ao2_ref(data, -1);
392 return NULL;
393
394 }
395
396 data->sockfd = socket(ast_sockaddr_is_ipv6(&data->remote_addr) ? AF_INET6 : AF_INET, SOCK_DGRAM, 0);
397 if (data->sockfd < 0) {
398 ast_log(AST_LOG_WARNING, "Failed to create socket for address %s: %s\n",
399 config->capture_address, strerror(errno));
400 ao2_ref(data, -1);
401 return NULL;
402 }
403
404 return data;
405}
406
407/*! \brief Destructor for a \ref hepv3_capture_info object */
408static void capture_info_dtor(void *obj)
409{
410 struct hepv3_capture_info *info = obj;
411
412 ast_free(info->uuid);
413 ast_free(info->payload);
414}
415
417{
419
420 if (!config) {
421 /* Well, that's unfortunate. Return something. */
423 }
424
425 return config->general->uuid_type;
426}
427
429{
431
432 return config && config->general->enabled;
433}
434
436{
437 struct hepv3_capture_info *info;
438
440 if (!info) {
441 return NULL;
442 }
443
444 info->payload = ast_malloc(len);
445 if (!info->payload) {
446 ao2_ref(info, -1);
447 return NULL;
448 }
449 memcpy(info->payload, payload, len);
450 info->len = len;
451
452 /* Set a reasonable default */
453 info->protocol_id = IPPROTO_UDP;
454
455 return info;
456}
457
458/*! \brief Callback function for the \ref hep_queue_tp taskprocessor */
459static int hep_queue_cb(void *data)
460{
462 RAII_VAR(struct hepv3_runtime_data *, hepv3_data, ao2_global_obj_ref(global_data), ao2_cleanup);
463 RAII_VAR(struct hepv3_capture_info *, capture_info, data, ao2_cleanup);
464 struct hep_generic hg_pkt;
465 unsigned int packet_len = 0, sock_buffer_len;
466 struct hep_chunk_ip4 ipv4_src, ipv4_dst;
467 struct hep_chunk_ip6 ipv6_src, ipv6_dst;
468 struct hep_chunk auth_key, payload, uuid, capturename;
469 void *sock_buffer;
470 int res;
471
472 if (!capture_info || !config || !hepv3_data) {
473 return 0;
474 }
475
476 if (ast_sockaddr_is_ipv4(&capture_info->src_addr) != ast_sockaddr_is_ipv4(&capture_info->dst_addr)) {
477 ast_log(AST_LOG_NOTICE, "Unable to send packet: Address Family mismatch between source/destination\n");
478 return -1;
479 }
480
481 packet_len = sizeof(hg_pkt);
482
483 /* Build HEPv3 header, capture info, and calculate the total packet size */
484 memcpy(hg_pkt.header.id, "\x48\x45\x50\x33", 4);
485
486 INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.ip_proto, CHUNK_TYPE_IP_PROTOCOL_ID, capture_info->protocol_id);
487 INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.src_port, CHUNK_TYPE_SRC_PORT, htons(ast_sockaddr_port(&capture_info->src_addr)));
488 INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.dst_port, CHUNK_TYPE_DST_PORT, htons(ast_sockaddr_port(&capture_info->dst_addr)));
489 INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.time_sec, CHUNK_TYPE_TIMESTAMP_SEC, htonl(capture_info->capture_time.tv_sec));
490 INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.time_usec, CHUNK_TYPE_TIMESTAMP_USEC, htonl(capture_info->capture_time.tv_usec));
491 INITIALIZE_GENERIC_HEP_CHUNK_DATA(&hg_pkt.proto_t, CHUNK_TYPE_PROTOCOL_TYPE, capture_info->capture_type);
493
494 if (ast_sockaddr_is_ipv4(&capture_info->src_addr)) {
497
499 inet_pton(AF_INET, ast_sockaddr_stringify_addr(&capture_info->src_addr), &ipv4_src.data);
500
502 inet_pton(AF_INET, ast_sockaddr_stringify_addr(&capture_info->dst_addr), &ipv4_dst.data);
503
504 packet_len += (sizeof(ipv4_src) + sizeof(ipv4_dst));
505 } else {
508
510 inet_pton(AF_INET6, ast_sockaddr_stringify_addr(&capture_info->src_addr), &ipv6_src.data);
511
513 inet_pton(AF_INET6, ast_sockaddr_stringify_addr(&capture_info->dst_addr), &ipv6_dst.data);
514
515 packet_len += (sizeof(ipv6_src) + sizeof(ipv6_dst));
516 }
517
518 if (!ast_strlen_zero(config->general->capture_password)) {
519 INITIALIZE_GENERIC_HEP_IDS_VAR(&auth_key, CHUNK_TYPE_AUTH_KEY, strlen(config->general->capture_password));
520 packet_len += (sizeof(auth_key) + strlen(config->general->capture_password));
521 }
522 if (!ast_strlen_zero(config->general->capture_name)) {
523 INITIALIZE_GENERIC_HEP_IDS_VAR(&capturename, CHUNK_TYPE_CAPTURE_AGENT_NAME, strlen(config->general->capture_name));
524 packet_len += (sizeof(capturename) + strlen(config->general->capture_name));
525 }
526 INITIALIZE_GENERIC_HEP_IDS_VAR(&uuid, CHUNK_TYPE_UUID, strlen(capture_info->uuid));
527 packet_len += (sizeof(uuid) + strlen(capture_info->uuid));
529 capture_info->zipped ? CHUNK_TYPE_PAYLOAD_ZIP : CHUNK_TYPE_PAYLOAD, capture_info->len);
530 packet_len += (sizeof(payload) + capture_info->len);
531 hg_pkt.header.length = htons(packet_len);
532
533 /* Build the buffer to send */
534 sock_buffer = ast_malloc(packet_len);
535 if (!sock_buffer) {
536 return -1;
537 }
538
539 /* Copy in the header */
540 memcpy(sock_buffer, &hg_pkt, sizeof(hg_pkt));
541 sock_buffer_len = sizeof(hg_pkt);
542
543 /* Addresses */
544 if (ast_sockaddr_is_ipv4(&capture_info->src_addr)) {
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);
549 } else {
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);
554 }
555
556 /* Auth Key */
557 if (!ast_strlen_zero(config->general->capture_password)) {
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);
562 }
563
564 /* UUID */
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);
569
570 /* Capture Agent Name */
571 if (!ast_strlen_zero(config->general->capture_name)) {
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);
576 }
577
578 /* Packet! */
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;
583
584 ast_assert(sock_buffer_len == packet_len);
585
586 res = ast_sendto(hepv3_data->sockfd, sock_buffer, sock_buffer_len, 0, &hepv3_data->remote_addr);
587 if (res < 0) {
588 ast_log(AST_LOG_ERROR, "Error [%d] while sending packet to HEPv3 server: %s\n",
589 errno, strerror(errno));
590 } else if (res != sock_buffer_len) {
591 ast_log(AST_LOG_WARNING, "Failed to send complete packet to HEPv3 server: %d of %u sent\n",
592 res, sock_buffer_len);
593 res = -1;
594 }
595
596 ast_free(sock_buffer);
597 return res;
598}
599
600int hepv3_send_packet(struct hepv3_capture_info *capture_info)
601{
603 int res;
604
605 if (!config || !config->general->enabled) {
606 ao2_ref(capture_info, -1);
607 return 0;
608 }
609
611 if (res == -1) {
612 ao2_ref(capture_info, -1);
613 }
614
615 return res;
616}
617
618/*!
619 * \brief Pre-apply callback for the config framework.
620 *
621 * This validates that required fields exist and are populated.
622 */
624{
625 struct module_config *config = aco_pending_config(&cfg_info);
626
627 if (!config->general->enabled) {
628 /* If we're not enabled, we don't care about anything else */
629 return 0;
630 }
631
632 if (ast_strlen_zero(config->general->capture_address)) {
633 ast_log(AST_LOG_ERROR, "Missing required configuration option 'capture_address'\n");
634 return -1;
635 }
636
637 return 0;
638}
639
640/*!
641 * \brief Post-apply callback for the config framework.
642 *
643 * This will create the run-time information from the supplied
644 * configuration.
645 */
646static void hepv3_config_post_apply(void)
647{
649 struct hepv3_runtime_data *data;
650
651 data = hepv3_data_alloc(mod_cfg->general);
652 if (!data) {
653 return;
654 }
655
656 ao2_global_obj_replace_unref(global_data, data);
657 ao2_ref(data, -1);
658}
659
660/*!
661 * \brief Reload the module
662 */
663static int reload_module(void)
664{
665 if (aco_process_config(&cfg_info, 1) == ACO_PROCESS_ERROR) {
666 return -1;
667 }
668 return 0;
669}
670
671/*!
672 * \brief Unload the module
673 */
674static int unload_module(void)
675{
677
679 ao2_global_obj_release(global_data);
680 aco_info_destroy(&cfg_info);
681
682 return 0;
683}
684
685/*!
686 * \brief Load the module
687 */
688static int load_module(void)
689{
690 if (aco_info_init(&cfg_info)) {
691 goto error;
692 }
693
695 if (!hep_queue_tp) {
696 goto error;
697 }
698
699 aco_option_register(&cfg_info, "enabled", ACO_EXACT, global_options, "yes", OPT_BOOL_T, 1, FLDSET(struct hepv3_global_config, enabled));
700 aco_option_register(&cfg_info, "capture_address", ACO_EXACT, global_options, "", OPT_STRINGFIELD_T, 1, STRFLDSET(struct hepv3_global_config, capture_address));
701 aco_option_register(&cfg_info, "capture_password", ACO_EXACT, global_options, "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct hepv3_global_config, capture_password));
702 aco_option_register(&cfg_info, "capture_id", ACO_EXACT, global_options, "0", OPT_UINT_T, 0, STRFLDSET(struct hepv3_global_config, capture_id));
703 aco_option_register(&cfg_info, "capture_name", ACO_EXACT, global_options, "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct hepv3_global_config, capture_name));
704 aco_option_register_custom(&cfg_info, "uuid_type", ACO_EXACT, global_options, "call-id", uuid_type_handler, 0);
705
706 if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
707 goto error;
708 }
709
711
712error:
713 aco_info_destroy(&cfg_info);
715}
716
718 .support_level = AST_MODULE_SUPPORT_EXTENDED,
719 .load = load_module,
720 .unload = unload_module,
722 .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
unsigned int u_int32_t
unsigned short u_int16_t
unsigned char u_int8_t
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
@ AST_AF_UNSPEC
Definition: netsock2.h:54
#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
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:272
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:348
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:109
@ CHUNK_TYPE_TIMESTAMP_USEC
Definition: res_hep.c:139
@ CHUNK_TYPE_PAYLOAD_ZIP
Definition: res_hep.c:157
@ CHUNK_TYPE_IPV4_DST_ADDR
Definition: res_hep.c:121
@ CHUNK_TYPE_IPV6_SRC_ADDR
Definition: res_hep.c:124
@ CHUNK_TYPE_IP_PROTOCOL_ID
Definition: res_hep.c:115
@ CHUNK_TYPE_DST_PORT
Definition: res_hep.c:133
@ CHUNK_TYPE_TIMESTAMP_SEC
Definition: res_hep.c:136
@ CHUNK_TYPE_PROTOCOL_TYPE
Definition: res_hep.c:142
@ CHUNK_TYPE_PAYLOAD
Definition: res_hep.c:154
@ CHUNK_TYPE_IPV4_SRC_ADDR
Definition: res_hep.c:118
@ CHUNK_TYPE_CAPTURE_AGENT_NAME
Definition: res_hep.c:163
@ CHUNK_TYPE_IPV6_DST_ADDR
Definition: res_hep.c:127
@ CHUNK_TYPE_AUTH_KEY
Definition: res_hep.c:151
@ CHUNK_TYPE_IP_PROTOCOL_FAMILY
Definition: res_hep.c:112
@ CHUNK_TYPE_UUID
Definition: res_hep.c:160
@ CHUNK_TYPE_SRC_PORT
Definition: res_hep.c:130
@ CHUNK_TYPE_KEEP_ALIVE_TIMER
Definition: res_hep.c:148
@ CHUNK_TYPE_CAPTURE_AGENT_ID
Definition: res_hep.c:145
static int hep_queue_cb(void *data)
Callback function for the hep_queue_tp taskprocessor.
Definition: res_hep.c:459
enum hep_uuid_type hepv3_get_uuid_type(void)
Get the preferred UUID type.
Definition: res_hep.c:416
#define INITIALIZE_GENERIC_HEP_CHUNK_DATA(hep_item, type, value)
Definition: res_hep.c:181
static struct ast_taskprocessor * hep_queue_tp
Definition: res_hep.c:285
static void * hepv3_config_alloc(void)
HEPv3 configuration object allocation.
Definition: res_hep.c:306
static struct hepv3_runtime_data * hepv3_data_alloc(struct hepv3_global_config *config)
Allocate the HEPv3 run-time data.
Definition: res_hep.c:378
int hepv3_is_loaded(void)
Return whether or not we're currently loaded and active.
Definition: res_hep.c:428
static AO2_GLOBAL_OBJ_STATIC(global_config)
The module configuration container.
static int reload_module(void)
Reload the module.
Definition: res_hep.c:663
static void hepv3_config_post_apply(void)
Post-apply callback for the config framework.
Definition: res_hep.c:646
struct aco_file hepv3_conf
Definition: res_hep.c:274
static void capture_info_dtor(void *obj)
Destructor for a hepv3_capture_info object.
Definition: res_hep.c:408
struct hepv3_capture_info * hepv3_create_capture_info(const void *payload, size_t len)
Create a hepv3_capture_info object.
Definition: res_hep.c:435
static void module_config_dtor(void *obj)
Configuration object destructor.
Definition: res_hep.c:319
static int hepv3_config_pre_apply(void)
Pre-apply callback for the config framework.
Definition: res_hep.c:623
#define INITIALIZE_GENERIC_HEP_CHUNK(hep_item, type)
Definition: res_hep.c:176
static int load_module(void)
Load the module.
Definition: res_hep.c:688
int hepv3_send_packet(struct hepv3_capture_info *capture_info)
Send a generic packet capture to HEPv3.
Definition: res_hep.c:600
static int unload_module(void)
Unload the module.
Definition: res_hep.c:674
#define INITIALIZE_GENERIC_HEP_IDS_VAR(hep_chunk, type, len)
Definition: res_hep.c:171
static void hepv3_config_dtor(void *obj)
Definition: res_hep.c:298
static void * module_config_alloc(void)
Module config constructor.
Definition: res_hep.c:329
static void hepv3_data_dtor(void *obj)
HEPv3 run-time data destructor.
Definition: res_hep.c:367
static struct aco_type global_option
Definition: res_hep.c:264
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
#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:213
struct in_addr data
Definition: res_hep.c:214
struct in6_addr data
Definition: res_hep.c:219
struct hep_chunk chunk
Definition: res_hep.c:218
struct hep_chunk chunk
Definition: res_hep.c:203
u_int16_t data
Definition: res_hep.c:204
u_int32_t data
Definition: res_hep.c:209
struct hep_chunk chunk
Definition: res_hep.c:208
struct hep_chunk chunk
Definition: res_hep.c:198
u_int8_t data
Definition: res_hep.c:199
u_int16_t type_id
Definition: res_hep.c:193
u_int16_t length
Definition: res_hep.c:194
u_int16_t vendor_id
Definition: res_hep.c:192
u_int16_t length
Definition: res_hep.c:224
char id[4]
Definition: res_hep.c:223
struct hep_chunk_uint8 ip_proto
Definition: res_hep.c:232
struct hep_ctrl header
Definition: res_hep.c:230
struct hep_chunk_uint8 proto_t
Definition: res_hep.c:237
struct hep_chunk_uint16 dst_port
Definition: res_hep.c:234
struct hep_chunk_uint32 capt_id
Definition: res_hep.c:238
struct hep_chunk_uint32 time_sec
Definition: res_hep.c:235
struct hep_chunk_uint8 ip_family
Definition: res_hep.c:231
struct hep_chunk_uint16 src_port
Definition: res_hep.c:233
struct hep_chunk_uint32 time_usec
Definition: res_hep.c:236
HEPv3 Capture Info.
Definition: res_hep.h:57
void * payload
Definition: res_hep.h:65
Global configuration for the module.
Definition: res_hep.c:242
const ast_string_field capture_password
Definition: res_hep.c:250
unsigned int capture_id
Definition: res_hep.c:244
enum hep_uuid_type uuid_type
Definition: res_hep.c:245
unsigned int enabled
Definition: res_hep.c:243
const ast_string_field capture_name
Definition: res_hep.c:250
const ast_string_field capture_address
Definition: res_hep.c:250
Run-time data derived from hepv3_global_config.
Definition: res_hep.c:259
struct ast_sockaddr remote_addr
Definition: res_hep.c:260
The configuration settings for this module.
Definition: cdr.c:264
struct hepv3_global_config * general
Definition: res_hep.c:255
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