Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
res_pjsip_endpoint_identifier_ip.c File Reference
#include "asterisk.h"
#include <pjsip.h>
#include "asterisk/res_pjsip.h"
#include "asterisk/res_pjsip_cli.h"
#include "asterisk/module.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "res_pjsip/include/res_pjsip_private.h"
Include dependency graph for res_pjsip_endpoint_identifier_ip.c:

Go to the source code of this file.

Data Structures

struct  ip_identify_match
 Structure for an IP identification matching object. More...
 

Macros

#define HOSTS_BUCKETS   53
 The number of buckets for storing hosts for resolution. More...
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static struct ao2_containercli_get_container (const char *regex)
 
static int cli_iterator (void *container, ao2_callback_fn callback, void *args)
 
static int cli_print_body (void *obj, void *arg, int flags)
 
static int cli_print_header (void *obj, void *arg, int flags)
 
static void * cli_retrieve_by_id (const char *id)
 
static struct ast_sip_endpointcommon_identify (ao2_callback_fn *identify_match_cb, void *arg)
 
static int format_ami_endpoint_identify (const struct ast_sip_endpoint *endpoint, struct ast_sip_ami *ami)
 
static struct ast_sip_endpointheader_identify (pjsip_rx_data *rdata)
 
static int header_identify_match_check (void *obj, void *arg, int flags)
 Comparator function for matching an object by header. More...
 
static struct ast_sip_endpointip_identify (pjsip_rx_data *rdata)
 
static void * ip_identify_alloc (const char *name)
 Allocator function for a matching object. More...
 
static int ip_identify_apply (const struct ast_sorcery *sorcery, void *obj)
 Apply handler for identify type. More...
 
static void ip_identify_destroy (void *obj)
 Destructor function for a matching object. More...
 
static int ip_identify_match_check (void *obj, void *arg, int flags)
 Comparator function for matching an object by IP address. More...
 
static int ip_identify_match_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 Custom handler for match field. More...
 
static int ip_identify_match_host_lookup (struct ip_identify_match *identify, const char *host)
 Helper function which performs a host lookup and adds result to identify match. More...
 
static int ip_identify_match_srv_lookup (struct ip_identify_match *identify, const char *prefix, const char *host, int results)
 Helper function which performs an SRV lookup and then resolves the hostname. More...
 
static int load_module (void)
 
static int match_to_str (const void *obj, const intptr_t *args, char **buf)
 
static int match_to_var_list (const void *obj, struct ast_variable **fields)
 
static void match_to_var_list_append (struct ast_variable **head, struct ast_ha *ha)
 
static char * my_cli_traverse_objects (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int reload_module (void)
 
static int send_identify_ami_event (void *obj, void *arg, void *data, int flags)
 
static int sip_identify_to_ami (const struct ip_identify_match *identify, struct ast_str **buf)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP IP endpoint identifier" , .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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .reload = reload_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND - 4, .requires = "res_pjsip", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_sip_cli_formatter_entrycli_formatter
 
static struct ast_cli_entry cli_identify []
 
struct ast_sip_endpoint_formatter endpoint_identify_formatter
 
static struct ast_sip_endpoint_identifier header_identifier
 
static struct ast_sip_endpoint_identifier ip_identifier
 

Macro Definition Documentation

◆ HOSTS_BUCKETS

#define HOSTS_BUCKETS   53

The number of buckets for storing hosts for resolution.

Definition at line 122 of file res_pjsip_endpoint_identifier_ip.c.

Referenced by ip_identify_match_handler().

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 905 of file res_pjsip_endpoint_identifier_ip.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 905 of file res_pjsip_endpoint_identifier_ip.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 905 of file res_pjsip_endpoint_identifier_ip.c.

◆ cli_get_container()

static struct ao2_container* cli_get_container ( const char *  regex)
static

Definition at line 698 of file res_pjsip_endpoint_identifier_ip.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, ao2_container_alloc_list, ao2_container_dup(), ao2_ref, ast_sip_get_sorcery(), ast_sorcery_object_id_compare(), ast_sorcery_object_id_sort(), ast_sorcery_retrieve_by_regex(), container, NULL, and RAII_VAR.

Referenced by load_module().

699 {
701  struct ao2_container *s_container;
702 
704  if (!container) {
705  return NULL;
706  }
707 
710  if (!s_container) {
711  return NULL;
712  }
713 
714  if (ao2_container_dup(s_container, container, 0)) {
715  ao2_ref(s_container, -1);
716  return NULL;
717  }
718 
719  return s_container;
720 }
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
Definition: sorcery.c:2459
#define NULL
Definition: resample.c:96
struct ao2_container * ast_sorcery_retrieve_by_regex(const struct ast_sorcery *sorcery, const char *type, const char *regex)
Retrieve multiple objects using a regular expression on their id.
Definition: sorcery.c:1949
#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:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
int ast_sorcery_object_id_sort(const void *obj, const void *arg, int flags)
ao2 object sorter based on sorcery id.
Definition: sorcery.c:2435
struct ao2_container * container
Definition: res_fax.c:502
int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags)
Copy all object references in the src container into the dest container.
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:948
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Generic container type.

◆ cli_iterator()

static int cli_iterator ( void *  container,
ao2_callback_fn  callback,
void *  args 
)
static

Definition at line 675 of file res_pjsip_endpoint_identifier_ip.c.

References ao2_callback, ao2_cleanup, AST_RETRIEVE_FLAG_MULTIPLE, ast_sip_get_sorcery(), ast_sorcery_object_get_id(), ast_sorcery_retrieve_by_fields(), container, ast_variable::name, NULL, and OBJ_NODATA.

Referenced by load_module().

676 {
677  const struct ast_sip_endpoint *endpoint = container;
678  struct ao2_container *identifies;
679 
680  struct ast_variable fields = {
681  .name = "endpoint",
682  .value = ast_sorcery_object_get_id(endpoint),
683  .next = NULL,
684  };
685 
686  identifies = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "identify",
687  AST_RETRIEVE_FLAG_MULTIPLE, &fields);
688  if (!identifies) {
689  return -1;
690  }
691 
692  ao2_callback(identifies, OBJ_NODATA, callback, args);
693  ao2_cleanup(identifies);
694 
695  return 0;
696 }
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
Structure for variables, used for configurations and for channel variables.
Return all matching objects.
Definition: sorcery.h:120
const char * args
#define NULL
Definition: resample.c:96
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
struct ao2_container * container
Definition: res_fax.c:502
An entity with which Asterisk communicates.
Definition: res_pjsip.h:812
void * ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields)
Retrieve an object or multiple objects using specific fields.
Definition: sorcery.c:1897
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Generic container type.

◆ cli_print_body()

static int cli_print_body ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 754 of file res_pjsip_endpoint_identifier_ip.c.

References ast_ha::addr, ast_assert, ast_free, AST_SENSE_ALLOW, ast_sip_cli_print_sorcery_objectset(), ast_sockaddr_cidr_bits(), ast_sockaddr_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_sorcery_object_get_id(), ast_str_append(), ast_str_create, ast_strlen_zero, CLI_INDENT_TO_SPACES, context, ip_identify_match::endpoint_name, ast_sip_cli_context::indent_level, match(), ip_identify_match::match_header, ip_identify_match::matches, MAX_OBJECT_FIELD, ast_ha::netmask, ast_ha::next, NULL, ast_sip_cli_context::output_buffer, RAII_VAR, ast_sip_cli_context::recurse, ast_ha::sense, ast_sip_cli_context::show_details, ast_sip_cli_context::show_details_only_level_0, and str.

Referenced by load_module().

755 {
757  struct ip_identify_match *ident = obj;
758  struct ast_sip_cli_context *context = arg;
759  struct ast_ha *match;
760  int indent;
761 
762  ast_assert(context->output_buffer != NULL);
763 
764  ast_str_append(&context->output_buffer, 0, "%*s: %s/%s\n",
765  CLI_INDENT_TO_SPACES(context->indent_level), "Identify",
767 
768  if (context->recurse) {
769  context->indent_level++;
770  indent = CLI_INDENT_TO_SPACES(context->indent_level);
771 
772  for (match = ident->matches; match; match = match->next) {
773  const char *addr;
774 
775  if (ast_sockaddr_port(&match->addr)) {
776  addr = ast_sockaddr_stringify(&match->addr);
777  } else {
778  addr = ast_sockaddr_stringify_addr(&match->addr);
779  }
780 
781  ast_str_append(&context->output_buffer, 0, "%*s: %s%s/%d\n",
782  indent,
783  "Match",
784  match->sense == AST_SENSE_ALLOW ? "!" : "",
785  addr, ast_sockaddr_cidr_bits(&match->netmask));
786  }
787 
788  if (!ast_strlen_zero(ident->match_header)) {
789  ast_str_append(&context->output_buffer, 0, "%*s: %s\n",
790  indent,
791  "Match",
792  ident->match_header);
793  }
794 
795  context->indent_level--;
796 
797  if (context->indent_level == 0) {
798  ast_str_append(&context->output_buffer, 0, "\n");
799  }
800  }
801 
802  if (context->show_details
803  || (context->show_details_only_level_0 && context->indent_level == 0)) {
804  ast_str_append(&context->output_buffer, 0, "\n");
805  ast_sip_cli_print_sorcery_objectset(ident, context, 0);
806  }
807 
808  return 0;
809 }
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:290
struct ast_ha * next
Definition: acl.h:56
struct ast_str * output_buffer
Definition: res_pjsip_cli.h:36
struct ast_sockaddr addr
Definition: acl.h:53
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
enum ast_acl_sense sense
Definition: acl.h:55
#define ast_assert(a)
Definition: utils.h:695
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2315
const char * str
Definition: app_jack.c:147
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
internal representation of ACL entries In principle user applications would have no need for this...
Definition: acl.h:51
struct ast_sockaddr netmask
Definition: acl.h:54
#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:911
#define CLI_INDENT_TO_SPACES(x)
Definition: res_pjsip_cli.h:29
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
#define MAX_OBJECT_FIELD
Maximum length of an object field name.
Definition: sorcery.h:110
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
#define ast_free(a)
Definition: astmm.h:182
int ast_sockaddr_cidr_bits(const struct ast_sockaddr *sa)
Count the 1 bits in a netmask.
Definition: netsock2.c:130
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
int ast_sip_cli_print_sorcery_objectset(void *obj, void *arg, int flags)
Prints a sorcery object&#39;s ast_variable list.
Definition: pjsip_cli.c:36
const ast_string_field endpoint_name
Structure for an IP identification matching object.
const ast_string_field match_header
struct ast_ha * matches
Networks or addresses that should match this.
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
unsigned show_details_only_level_0
Definition: res_pjsip_cli.h:46

◆ cli_print_header()

static int cli_print_header ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 727 of file res_pjsip_endpoint_identifier_ip.c.

References ast_assert, ast_str_append(), CLI_HEADER_FILLER, CLI_INDENT_TO_SPACES, CLI_LAST_TABSTOP, CLI_MAX_WIDTH, context, ast_sip_cli_context::indent_level, NULL, ast_sip_cli_context::output_buffer, and ast_sip_cli_context::recurse.

Referenced by load_module().

728 {
729  struct ast_sip_cli_context *context = arg;
730  int indent = CLI_INDENT_TO_SPACES(context->indent_level);
731  int filler = CLI_MAX_WIDTH - indent - 22;
732 
733  ast_assert(context->output_buffer != NULL);
734 
735  ast_str_append(&context->output_buffer, 0,
736  "%*s: <Identify/Endpoint%*.*s>\n",
737  indent, "Identify", filler, filler, CLI_HEADER_FILLER);
738 
739  if (context->recurse) {
740  context->indent_level++;
741  indent = CLI_INDENT_TO_SPACES(context->indent_level);
742  filler = CLI_LAST_TABSTOP - indent - 24;
743 
744  ast_str_append(&context->output_buffer, 0,
745  "%*s: <criteria%*.*s>\n",
746  indent, "Match", filler, filler, CLI_HEADER_FILLER);
747 
748  context->indent_level--;
749  }
750 
751  return 0;
752 }
struct ast_str * output_buffer
Definition: res_pjsip_cli.h:36
#define CLI_LAST_TABSTOP
Definition: res_pjsip_cli.h:27
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
#define CLI_INDENT_TO_SPACES(x)
Definition: res_pjsip_cli.h:29
#define CLI_MAX_WIDTH
Definition: res_pjsip_cli.h:26
#define CLI_HEADER_FILLER
Definition: res_pjsip_cli.h:24
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

◆ cli_retrieve_by_id()

static void* cli_retrieve_by_id ( const char *  id)
static

Definition at line 722 of file res_pjsip_endpoint_identifier_ip.c.

References ast_sip_get_sorcery(), and ast_sorcery_retrieve_by_id().

Referenced by load_module().

723 {
724  return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "identify", id);
725 }
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1853
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.

◆ common_identify()

static struct ast_sip_endpoint* common_identify ( ao2_callback_fn identify_match_cb,
void *  arg 
)
static

Definition at line 265 of file res_pjsip_endpoint_identifier_ip.c.

References ao2_callback, ao2_cleanup, ao2_container_count(), ao2_ref, ast_debug, ast_log, AST_RETRIEVE_FLAG_ALL, AST_RETRIEVE_FLAG_MULTIPLE, ast_sip_get_sorcery(), ast_sorcery_object_get_id(), ast_sorcery_retrieve_by_fields(), ast_sorcery_retrieve_by_id(), ip_identify_match::endpoint_name, LOG_WARNING, match(), NULL, and RAII_VAR.

Referenced by header_identify(), and ip_identify().

266 {
267  RAII_VAR(struct ao2_container *, candidates, NULL, ao2_cleanup);
268  struct ip_identify_match *match;
269  struct ast_sip_endpoint *endpoint;
270 
271  /* If no possibilities exist return early to save some time */
272  candidates = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "identify",
274  if (!candidates || !ao2_container_count(candidates)) {
275  ast_debug(3, "No identify sections to match against\n");
276  return NULL;
277  }
278 
279  match = ao2_callback(candidates, 0, identify_match_cb, arg);
280  if (!match) {
281  return NULL;
282  }
283 
284  endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
285  match->endpoint_name);
286  if (endpoint) {
287  ast_debug(3, "Identify '%s' SIP message matched to endpoint %s\n",
289  } else {
290  ast_log(LOG_WARNING, "Identify '%s' points to endpoint '%s' but endpoint could not be found\n",
292  }
293 
294  ao2_ref(match, -1);
295  return endpoint;
296 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define LOG_WARNING
Definition: logger.h:274
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
Perform no matching, return all objects.
Definition: sorcery.h:123
Return all matching objects.
Definition: sorcery.h:120
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2315
#define NULL
Definition: resample.c:96
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1853
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#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:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
An entity with which Asterisk communicates.
Definition: res_pjsip.h:812
void * ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields)
Retrieve an object or multiple objects using specific fields.
Definition: sorcery.c:1897
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Generic container type.
const ast_string_field endpoint_name
Structure for an IP identification matching object.

◆ format_ami_endpoint_identify()

static int format_ami_endpoint_identify ( const struct ast_sip_endpoint endpoint,
struct ast_sip_ami ami 
)
static

Definition at line 646 of file res_pjsip_endpoint_identifier_ip.c.

References ao2_callback_data, ao2_ref, AST_RETRIEVE_FLAG_MULTIPLE, ast_sip_get_sorcery(), ast_sorcery_object_get_id(), ast_sorcery_retrieve_by_fields(), ast_variable::name, OBJ_MULTIPLE, OBJ_NODATA, and send_identify_ami_event().

648 {
649  struct ao2_container *identifies;
650  struct ast_variable fields = {
651  .name = "endpoint",
652  .value = ast_sorcery_object_get_id(endpoint),
653  };
654 
655  identifies = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "identify",
656  AST_RETRIEVE_FLAG_MULTIPLE, &fields);
657  if (!identifies) {
658  return -1;
659  }
660 
661  /* Build and send any found identify object's AMI IdentifyDetail event. */
664  (void *) ast_sorcery_object_get_id(endpoint),
665  ami);
666 
667  ao2_ref(identifies, -1);
668  return 0;
669 }
Structure for variables, used for configurations and for channel variables.
Return all matching objects.
Definition: sorcery.h:120
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
static int send_identify_ami_event(void *obj, void *arg, void *data, int flags)
#define ao2_callback_data(container, flags, cb_fn, arg, data)
Definition: astobj2.h:1743
void * ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields)
Retrieve an object or multiple objects using specific fields.
Definition: sorcery.c:1897
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
Generic container type.

◆ header_identify()

static struct ast_sip_endpoint* header_identify ( pjsip_rx_data *  rdata)
static

Definition at line 312 of file res_pjsip_endpoint_identifier_ip.c.

References common_identify(), and header_identify_match_check().

313 {
315 }
static struct ast_sip_endpoint * common_identify(ao2_callback_fn *identify_match_cb, void *arg)
static int header_identify_match_check(void *obj, void *arg, int flags)
Comparator function for matching an object by header.

◆ header_identify_match_check()

static int header_identify_match_check ( void *  obj,
void *  arg,
int  flags 
)
static

Comparator function for matching an object by header.

Definition at line 178 of file res_pjsip_endpoint_identifier_ip.c.

References ast_assert, ast_debug, ast_sorcery_object_get_id(), ast_strip(), ast_strlen_zero, buf, CMP_MATCH, ip_identify_match::is_regex, len(), ip_identify_match::match_header, ip_identify_match::match_header_name, ip_identify_match::match_header_value, NULL, PATH_MAX, and ip_identify_match::regex_buf.

Referenced by header_identify().

179 {
180  struct ip_identify_match *identify = obj;
181  struct pjsip_rx_data *rdata = arg;
182  pjsip_hdr *header;
183  pj_str_t pj_header_name;
184  int header_present;
185 
186  if (ast_strlen_zero(identify->match_header)) {
187  return 0;
188  }
189 
190  pj_header_name = pj_str((void *) identify->match_header_name);
191 
192  /* Check all headers of the given name for a match. */
193  header_present = 0;
194  for (header = NULL;
195  (header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &pj_header_name, header));
196  header = header->next) {
197  char *pos;
198  int len;
199  char buf[PATH_MAX];
200 
201  header_present = 1;
202 
203  /* Print header line to buf */
204  len = pjsip_hdr_print_on(header, buf, sizeof(buf) - 1);
205  if (len < 0) {
206  /* Buffer not large enough or no header vptr! */
207  ast_assert(0);
208  continue;
209  }
210  buf[len] = '\0';
211 
212  /* Remove header name from pj_buf and trim blanks. */
213  pos = strchr(buf, ':');
214  if (!pos) {
215  /* No header name? Bug in PJPROJECT if so. */
216  ast_assert(0);
217  continue;
218  }
219  pos = ast_strip(pos + 1);
220 
221  /* Does header value match what we are looking for? */
222  if (identify->is_regex) {
223  if (!regexec(&identify->regex_buf, pos, 0, NULL, 0)) {
224  return CMP_MATCH;
225  }
226  } else if (!strcmp(identify->match_header_value, pos)) {
227  return CMP_MATCH;
228  }
229 
230  ast_debug(3, "Identify '%s': SIP message has '%s' header but value '%s' does not match '%s'.\n",
231  ast_sorcery_object_get_id(identify),
232  identify->match_header_name,
233  pos,
234  identify->match_header_value);
235  }
236  if (!header_present) {
237  ast_debug(3, "Identify '%s': SIP message does not have '%s' header.\n",
238  ast_sorcery_object_get_id(identify),
239  identify->match_header_name);
240  }
241  return 0;
242 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
const ast_string_field match_header_name
#define PATH_MAX
Definition: asterisk.h:40
Structure for an IP identification matching object.
const ast_string_field match_header
const ast_string_field match_header_value

◆ ip_identify()

static struct ast_sip_endpoint* ip_identify ( pjsip_rx_data *  rdata)
static

Definition at line 298 of file res_pjsip_endpoint_identifier_ip.c.

References ast_sockaddr_parse(), ast_sockaddr_set_port, common_identify(), ip_identify_match_check(), and PARSE_PORT_FORBID.

299 {
300  struct ast_sockaddr addr = { { 0, } };
301 
302  ast_sockaddr_parse(&addr, rdata->pkt_info.src_name, PARSE_PORT_FORBID);
303  ast_sockaddr_set_port(&addr, rdata->pkt_info.src_port);
304 
306 }
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
static struct ast_sip_endpoint * common_identify(ao2_callback_fn *identify_match_cb, void *arg)
Socket address structure.
Definition: netsock2.h:97
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
static int ip_identify_match_check(void *obj, void *arg, int flags)
Comparator function for matching an object by IP address.

◆ ip_identify_alloc()

static void* ip_identify_alloc ( const char *  name)
static

Allocator function for a matching object.

Definition at line 165 of file res_pjsip_endpoint_identifier_ip.c.

References ao2_cleanup, ast_sorcery_generic_alloc(), ast_string_field_init, ip_identify_destroy(), and NULL.

Referenced by load_module().

166 {
167  struct ip_identify_match *identify = ast_sorcery_generic_alloc(sizeof(*identify), ip_identify_destroy);
168 
169  if (!identify || ast_string_field_init(identify, 256)) {
170  ao2_cleanup(identify);
171  return NULL;
172  }
173 
174  return identify;
175 }
#define NULL
Definition: resample.c:96
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
Definition: sorcery.c:1728
Structure for an IP identification matching object.
static void ip_identify_destroy(void *obj)
Destructor function for a matching object.

◆ ip_identify_apply()

static int ip_identify_apply ( const struct ast_sorcery sorcery,
void *  obj 
)
static

Apply handler for identify type.

Definition at line 443 of file res_pjsip_endpoint_identifier_ip.c.

References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_log, ast_sorcery_object_get_id(), ast_sorcery_object_set_has_dynamic_contents(), ast_strdupa, ast_string_field_set, ast_strip(), ast_strlen_zero, ip_identify_match::endpoint_name, ip_identify_match::hosts, ip_identify_match_host_lookup(), ip_identify_match_srv_lookup(), ip_identify_match::is_regex, len(), LOG_ERROR, LOG_WARNING, ip_identify_match::match_header, ip_identify_match::match_header_name, ip_identify_match::match_header_value, ip_identify_match::matches, NULL, ip_identify_match::regex_buf, and ip_identify_match::srv_lookups.

Referenced by load_module().

444 {
445  struct ip_identify_match *identify = obj;
446  char *current_string;
447  struct ao2_iterator i;
448 
449  /* Validate the identify object configuration */
450  if (ast_strlen_zero(identify->endpoint_name)) {
451  ast_log(LOG_ERROR, "Identify '%s' missing required endpoint name.\n",
452  ast_sorcery_object_get_id(identify));
453  return -1;
454  }
455  if (ast_strlen_zero(identify->match_header) /* No header to match */
456  /* and no static IP addresses with a mask */
457  && !identify->matches
458  /* and no addresses to resolve */
459  && (!identify->hosts || !ao2_container_count(identify->hosts))) {
460  ast_log(LOG_ERROR, "Identify '%s' is not configured to match anything.\n",
461  ast_sorcery_object_get_id(identify));
462  return -1;
463  }
464 
465  if (!ast_strlen_zero(identify->match_header)) {
466  char *c_header;
467  char *c_value;
468  int len;
469 
470  /* Split the header name and value */
471  c_header = ast_strdupa(identify->match_header);
472  c_value = strchr(c_header, ':');
473  if (!c_value) {
474  ast_log(LOG_ERROR, "Identify '%s' missing ':' separator in match_header '%s'.\n",
475  ast_sorcery_object_get_id(identify), identify->match_header);
476  return -1;
477  }
478  *c_value = '\0';
479  c_value = ast_strip(c_value + 1);
480  c_header = ast_strip(c_header);
481 
482  if (ast_strlen_zero(c_header)) {
483  ast_log(LOG_ERROR, "Identify '%s' has no SIP header to match in match_header '%s'.\n",
484  ast_sorcery_object_get_id(identify), identify->match_header);
485  return -1;
486  }
487 
488  if (!strcmp(c_value, "//")) {
489  /* An empty regex is the same as an empty literal string. */
490  c_value = "";
491  }
492 
493  if (ast_string_field_set(identify, match_header_name, c_header)
494  || ast_string_field_set(identify, match_header_value, c_value)) {
495  return -1;
496  }
497 
498  len = strlen(c_value);
499  if (2 < len && c_value[0] == '/' && c_value[len - 1] == '/') {
500  /* Make "/regex/" into "regex" */
501  c_value[len - 1] = '\0';
502  ++c_value;
503 
504  if (regcomp(&identify->regex_buf, c_value, REG_EXTENDED | REG_NOSUB)) {
505  ast_log(LOG_ERROR, "Identify '%s' failed to compile match_header regex '%s'.\n",
506  ast_sorcery_object_get_id(identify), c_value);
507  return -1;
508  }
509  identify->is_regex = 1;
510  }
511  }
512 
513  if (!identify->hosts) {
514  /* No match addresses to resolve */
515  return 0;
516  }
517 
518  /* Hosts can produce dynamic content, so mark the identify as such */
520 
521  /* Resolve the match addresses now */
522  i = ao2_iterator_init(identify->hosts, 0);
523  while ((current_string = ao2_iterator_next(&i))) {
524  int results = 0;
525  char *colon = strrchr(current_string, ':');
526 
527  /* We skip SRV lookup if a colon is present, assuming a port was specified */
528  if (!colon) {
529  /* No port, and we know this is not an IP address, so perform SRV resolution on it */
530  if (identify->srv_lookups) {
531  results = ip_identify_match_srv_lookup(identify, "_sip._udp", current_string,
532  results);
533  if (results != -1) {
534  results = ip_identify_match_srv_lookup(identify, "_sip._tcp",
535  current_string, results);
536  }
537  if (results != -1) {
538  results = ip_identify_match_srv_lookup(identify, "_sips._tcp",
539  current_string, results);
540  }
541  }
542  }
543 
544  /* If SRV fails fall back to a normal lookup on the host itself */
545  if (!results) {
546  results = ip_identify_match_host_lookup(identify, current_string);
547  }
548 
549  if (results == 0) {
550  ast_log(LOG_WARNING, "Identify '%s' provided address '%s' did not resolve to any address\n",
551  ast_sorcery_object_get_id(identify), current_string);
552  } else if (results == -1) {
553  ast_log(LOG_ERROR, "Identify '%s' failed when adding resolution results of '%s'\n",
554  ast_sorcery_object_get_id(identify), current_string);
555  ao2_ref(current_string, -1);
557  return -1;
558  }
559 
560  ao2_ref(current_string, -1);
561  }
563 
564  ao2_ref(identify->hosts, -1);
565  identify->hosts = NULL;
566 
567  return 0;
568 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define LOG_WARNING
Definition: logger.h:274
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define NULL
Definition: resample.c:96
static int ip_identify_match_srv_lookup(struct ip_identify_match *identify, const char *prefix, const char *host, int results)
Helper function which performs an SRV lookup and then resolves the hostname.
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ao2_container * hosts
Hosts to be resolved when applying configuration.
static int ip_identify_match_host_lookup(struct ip_identify_match *identify, const char *host)
Helper function which performs a host lookup and adds result to identify match.
#define ast_log
Definition: astobj2.c:42
unsigned int srv_lookups
Perform SRV resolution of hostnames.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
#define LOG_ERROR
Definition: logger.h:285
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
void ast_sorcery_object_set_has_dynamic_contents(const void *object)
Set the dynamic contents flag on a sorcery object.
Definition: sorcery.c:2379
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
const ast_string_field endpoint_name
Structure for an IP identification matching object.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
const ast_string_field match_header
struct ast_ha * matches
Networks or addresses that should match this.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ ip_identify_destroy()

static void ip_identify_destroy ( void *  obj)
static

Destructor function for a matching object.

Definition at line 152 of file res_pjsip_endpoint_identifier_ip.c.

References ao2_cleanup, ast_free_ha(), ast_string_field_free_memory, ip_identify_match::hosts, ip_identify_match::is_regex, ip_identify_match::matches, and ip_identify_match::regex_buf.

Referenced by ip_identify_alloc().

153 {
154  struct ip_identify_match *identify = obj;
155 
157  ast_free_ha(identify->matches);
158  ao2_cleanup(identify->hosts);
159  if (identify->is_regex) {
160  regfree(&identify->regex_buf);
161  }
162 }
struct ao2_container * hosts
Hosts to be resolved when applying configuration.
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
Definition: acl.c:222
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Structure for an IP identification matching object.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368
struct ast_ha * matches
Networks or addresses that should match this.

◆ ip_identify_match_check()

static int ip_identify_match_check ( void *  obj,
void *  arg,
int  flags 
)
static

Comparator function for matching an object by IP address.

Definition at line 245 of file res_pjsip_endpoint_identifier_ip.c.

References ast_apply_ha(), ast_debug, AST_SENSE_ALLOW, ast_sockaddr_stringify(), ast_sorcery_object_get_id(), CMP_MATCH, and ip_identify_match::matches.

Referenced by ip_identify().

246 {
247  struct ip_identify_match *identify = obj;
248  struct ast_sockaddr *addr = arg;
249  int sense;
250 
251  sense = ast_apply_ha(identify->matches, addr);
252  if (sense != AST_SENSE_ALLOW) {
253  ast_debug(3, "Source address %s matches identify '%s'\n",
255  ast_sorcery_object_get_id(identify));
256  return CMP_MATCH;
257  } else {
258  ast_debug(3, "Source address %s does not match identify '%s'\n",
260  ast_sorcery_object_get_id(identify));
261  return 0;
262  }
263 }
enum ast_acl_sense ast_apply_ha(const struct ast_ha *ha, const struct ast_sockaddr *addr)
Apply a set of rules to a given IP address.
Definition: acl.c:808
Socket address structure.
Definition: netsock2.h:97
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
Structure for an IP identification matching object.
struct ast_ha * matches
Networks or addresses that should match this.

◆ ip_identify_match_handler()

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

Custom handler for match field.

Definition at line 387 of file res_pjsip_endpoint_identifier_ip.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ast_append_ha_with_port(), ast_log, ast_sockaddr_parse(), ast_sorcery_object_get_id(), ast_str_container_add(), ast_str_container_alloc_options(), ast_strdupa, ast_strip(), ast_strlen_zero, error(), ip_identify_match::hosts, HOSTS_BUCKETS, LOG_ERROR, ip_identify_match::matches, strsep(), and ast_variable::value.

Referenced by load_module().

388 {
389  struct ip_identify_match *identify = obj;
390  char *input_string = ast_strdupa(var->value);
391  char *current_string;
392 
393  if (ast_strlen_zero(var->value)) {
394  return 0;
395  }
396 
397  while ((current_string = ast_strip(strsep(&input_string, ",")))) {
398  char *mask;
399  struct ast_sockaddr address;
400  int error = 0;
401 
402  if (ast_strlen_zero(current_string)) {
403  continue;
404  }
405 
406  mask = strrchr(current_string, '/');
407 
408  /* If it looks like a netmask is present, or we can immediately parse as an IP,
409  * hand things off to the ACL */
410  if (mask || ast_sockaddr_parse(&address, current_string, 0)) {
411  identify->matches = ast_append_ha_with_port("d", current_string, identify->matches, &error);
412 
413  if (!identify->matches || error) {
414  ast_log(LOG_ERROR, "Failed to add address '%s' to ip endpoint identifier '%s'\n",
415  current_string, ast_sorcery_object_get_id(obj));
416  return -1;
417  }
418 
419  continue;
420  }
421 
422  if (!identify->hosts) {
424  if (!identify->hosts) {
425  ast_log(LOG_ERROR, "Failed to create container to store hosts on ip endpoint identifier '%s'\n",
427  return -1;
428  }
429  }
430 
431  error = ast_str_container_add(identify->hosts, current_string);
432  if (error) {
433  ast_log(LOG_ERROR, "Failed to store host '%s' for resolution on ip endpoint identifier '%s'\n",
434  current_string, ast_sorcery_object_get_id(obj));
435  return -1;
436  }
437  }
438 
439  return 0;
440 }
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
char * address
Definition: f2c.h:59
Socket address structure.
Definition: netsock2.h:97
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ao2_container * hosts
Hosts to be resolved when applying configuration.
#define ast_log
Definition: astobj2.c:42
struct ao2_container * ast_str_container_alloc_options(enum ao2_alloc_opts opts, int buckets)
Allocates a hash container for bare strings.
Definition: strings.c:201
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define HOSTS_BUCKETS
The number of buckets for storing hosts for resolution.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
#define LOG_ERROR
Definition: logger.h:285
char * strsep(char **str, const char *delims)
struct ast_ha * ast_append_ha_with_port(const char *sense, const char *stuff, struct ast_ha *path, int *error)
Add a new rule with optional port to a list of HAs.
Definition: acl.c:718
int error(const char *format,...)
Definition: utils/frame.c:999
Structure for an IP identification matching object.
int ast_str_container_add(struct ao2_container *str_container, const char *add)
Adds a string to a string container allocated by ast_str_container_alloc.
Definition: strings.c:206
struct ast_ha * matches
Networks or addresses that should match this.

◆ ip_identify_match_host_lookup()

static int ip_identify_match_host_lookup ( struct ip_identify_match identify,
const char *  host 
)
static

Helper function which performs a host lookup and adds result to identify match.

Definition at line 322 of file res_pjsip_endpoint_identifier_ip.c.

References AST_AF_UNSPEC, ast_append_ha_with_port(), ast_apply_ha(), ast_free, AST_SENSE_ALLOW, ast_sockaddr_resolve(), ast_sockaddr_stringify(), error(), and ip_identify_match::matches.

Referenced by ip_identify_apply(), and ip_identify_match_srv_lookup().

323 {
324  struct ast_sockaddr *addrs;
325  int num_addrs = 0, error = 0, i;
326  int results = 0;
327 
328  num_addrs = ast_sockaddr_resolve(&addrs, host, 0, AST_AF_UNSPEC);
329  if (!num_addrs) {
330  return -1;
331  }
332 
333  for (i = 0; i < num_addrs; ++i) {
334  /* Check if the address is already in the list, if so don't add it again */
335  if (identify->matches && (ast_apply_ha(identify->matches, &addrs[i]) != AST_SENSE_ALLOW)) {
336  continue;
337  }
338 
339  /* We deny what we actually want to match because there is an implicit permit all rule for ACLs */
340  identify->matches = ast_append_ha_with_port("d", ast_sockaddr_stringify(&addrs[i]), identify->matches, &error);
341 
342  if (!identify->matches || error) {
343  results = -1;
344  break;
345  }
346 
347  results += 1;
348  }
349 
350  ast_free(addrs);
351 
352  return results;
353 }
enum ast_acl_sense ast_apply_ha(const struct ast_ha *ha, const struct ast_sockaddr *addr)
Apply a set of rules to a given IP address.
Definition: acl.c:808
Socket address structure.
Definition: netsock2.h:97
static char host[256]
Definition: muted.c:77
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
#define ast_free(a)
Definition: astmm.h:182
struct ast_ha * ast_append_ha_with_port(const char *sense, const char *stuff, struct ast_ha *path, int *error)
Add a new rule with optional port to a list of HAs.
Definition: acl.c:718
int error(const char *format,...)
Definition: utils/frame.c:999
struct ast_ha * matches
Networks or addresses that should match this.
int ast_sockaddr_resolve(struct ast_sockaddr **addrs, const char *str, int flags, int family)
Parses a string with an IPv4 or IPv6 address and place results into an array.
Definition: netsock2.c:280

◆ ip_identify_match_srv_lookup()

static int ip_identify_match_srv_lookup ( struct ip_identify_match identify,
const char *  prefix,
const char *  host,
int  results 
)
static

Helper function which performs an SRV lookup and then resolves the hostname.

Definition at line 356 of file res_pjsip_endpoint_identifier_ip.c.

References ast_srv_cleanup(), ast_srv_lookup(), context, ip_identify_match::hosts, ip_identify_match_host_lookup(), NULL, and service.

Referenced by ip_identify_apply().

357 {
358  char service[NI_MAXHOST];
359  struct srv_context *context = NULL;
360  int srv_ret;
361  const char *srvhost;
362  unsigned short srvport;
363 
364  snprintf(service, sizeof(service), "%s.%s", prefix, host);
365 
366  while (!(srv_ret = ast_srv_lookup(&context, service, &srvhost, &srvport))) {
367  int hosts;
368 
369  /* In the case of the SRV lookup we don't care if it fails, we will output a log message
370  * when we fallback to a normal lookup.
371  */
372  hosts = ip_identify_match_host_lookup(identify, srvhost);
373  if (hosts == -1) {
374  results = -1;
375  break;
376  } else {
377  results += hosts;
378  }
379  }
380 
381  ast_srv_cleanup(&context);
382 
383  return results;
384 }
void ast_srv_cleanup(struct srv_context **context)
Cleanup resources associated with ast_srv_lookup.
Definition: srv.c:248
enum ast_cc_service_type service
Definition: chan_sip.c:949
#define NULL
Definition: resample.c:96
static int ip_identify_match_host_lookup(struct ip_identify_match *identify, const char *host)
Helper function which performs a host lookup and adds result to identify match.
static char host[256]
Definition: muted.c:77
int ast_srv_lookup(struct srv_context **context, const char *service, const char **host, unsigned short *port)
Retrieve set of SRV lookups, in order.
Definition: srv.c:202
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
static char prefix[MAX_PREFIX]
Definition: http.c:141

◆ load_module()

static int load_module ( void  )
static

Definition at line 841 of file res_pjsip_endpoint_identifier_ip.c.

References ao2_alloc, ARRAY_LEN, ast_cli_register_multiple, ast_log, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_sip_get_sorcery(), ast_sip_register_cli_formatter(), ast_sip_register_endpoint_formatter(), ast_sip_register_endpoint_identifier_with_name(), ast_sorcery_apply_config, ast_sorcery_apply_default, ast_sorcery_load_object(), ast_sorcery_object_field_register, ast_sorcery_object_field_register_custom, ast_sorcery_object_get_id(), ast_sorcery_object_register, cli_get_container(), cli_iterator(), cli_print_body(), cli_print_header(), cli_retrieve_by_id(), ip_identify_match::endpoint_name, FLDSET, ast_sip_cli_formatter_entry::get_container, ast_sip_cli_formatter_entry::get_id, ip_identify_alloc(), ip_identify_apply(), ip_identify_match_handler(), ast_sip_cli_formatter_entry::iterate, LOG_ERROR, ip_identify_match::match_header, match_to_str(), match_to_var_list(), ast_sip_cli_formatter_entry::name, NULL, OPT_BOOL_T, OPT_NOOP_T, OPT_STRINGFIELD_T, ast_sip_cli_formatter_entry::print_body, ast_sip_cli_formatter_entry::print_header, ast_sip_cli_formatter_entry::retrieve_by_id, ip_identify_match::srv_lookups, and STRFLDSET.

Referenced by unload_module().

842 {
843  ast_sorcery_apply_config(ast_sip_get_sorcery(), "res_pjsip_endpoint_identifier_ip");
844  ast_sorcery_apply_default(ast_sip_get_sorcery(), "identify", "config", "pjsip.conf,criteria=type=identify");
845 
848  }
849 
850  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "type", "", OPT_NOOP_T, 0, 0);
851  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "endpoint", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, endpoint_name));
853  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "match_header", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, match_header));
854  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "srv_lookups", "yes", OPT_BOOL_T, 1, FLDSET(struct ip_identify_match, srv_lookups));
856 
860 
862  if (!cli_formatter) {
863  ast_log(LOG_ERROR, "Unable to allocate memory for cli formatter\n");
865  }
866  cli_formatter->name = "identify";
873 
876 
878 }
struct ao2_container *(* get_container)(const char *regex)
Definition: res_pjsip_cli.h:64
static struct ast_cli_entry cli_identify[]
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
Definition: res_pjsip_cli.h:52
int(* iterate)(void *container, ao2_callback_fn callback, void *args)
Definition: res_pjsip_cli.h:66
Type for a default handler that should do nothing.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
#define ast_sorcery_apply_config(sorcery, name)
Definition: sorcery.h:456
#define NULL
Definition: resample.c:96
void ast_sorcery_load_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to load persistent objects.
Definition: sorcery.c:1393
static struct ast_sip_endpoint_identifier ip_identifier
int ast_sip_register_cli_formatter(struct ast_sip_cli_formatter_entry *formatter)
Registers a CLI formatter.
Definition: pjsip_cli.c:310
void ast_sip_register_endpoint_formatter(struct ast_sip_endpoint_formatter *obj)
Register an endpoint formatter.
Definition: res_pjsip.c:3679
#define ast_log
Definition: astobj2.c:42
#define ast_sorcery_object_field_register_custom(sorcery, type, name, default_val, config_handler, sorcery_handler, multiple_handler, flags,...)
Register a field within an object with custom handlers.
Definition: sorcery.h:1005
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
static struct ast_sip_endpoint_identifier header_identifier
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
void *(* retrieve_by_id)(const char *id)
Definition: res_pjsip_cli.h:68
static struct ast_sip_cli_formatter_entry * cli_formatter
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
Definition: sorcery.h:838
#define LOG_ERROR
Definition: logger.h:285
Type for default option handler for bools (ast_true/ast_false)
#define ast_sorcery_apply_default(sorcery, type, name, data)
Definition: sorcery.h:477
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
static int match_to_str(const void *obj, const intptr_t *args, char **buf)
static void * ip_identify_alloc(const char *name)
Allocator function for a matching object.
struct ast_sip_endpoint_formatter endpoint_identify_formatter
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
const char *(* get_id)(const void *obj)
Definition: res_pjsip_cli.h:70
static int ip_identify_apply(const struct ast_sorcery *sorcery, void *obj)
Apply handler for identify type.
#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object.
Definition: sorcery.h:955
static int cli_print_header(void *obj, void *arg, int flags)
static int cli_iterator(void *container, ao2_callback_fn callback, void *args)
static struct ao2_container * cli_get_container(const char *regex)
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
int ast_sip_register_endpoint_identifier_with_name(struct ast_sip_endpoint_identifier *identifier, const char *name)
Register a SIP endpoint identifier with a name.
Definition: res_pjsip.c:3431
static void * cli_retrieve_by_id(const char *id)
Type for default option handler for stringfields.
ao2_callback_fn * print_header
Definition: res_pjsip_cli.h:60
static int match_to_var_list(const void *obj, struct ast_variable **fields)
static int cli_print_body(void *obj, void *arg, int flags)
static int ip_identify_match_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom handler for match field.
ao2_callback_fn * print_body
Definition: res_pjsip_cli.h:62
const char * name
Definition: res_pjsip_cli.h:58
Structure for an IP identification matching object.

◆ match_to_str()

static int match_to_str ( const void *  obj,
const intptr_t *  args,
char **  buf 
)
static

Definition at line 570 of file res_pjsip_endpoint_identifier_ip.c.

References ast_free, ast_ha_join(), ast_str_buffer(), ast_str_create, ast_strdup, ip_identify_match::matches, MAX_OBJECT_FIELD, RAII_VAR, and str.

Referenced by load_module().

571 {
573  const struct ip_identify_match *identify = obj;
574 
575  ast_ha_join(identify->matches, &str);
577  return 0;
578 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
const char * str
Definition: app_jack.c:147
void ast_ha_join(const struct ast_ha *ha, struct ast_str **buf)
Convert HAs to a comma separated string value.
Definition: acl.c:723
#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:911
#define MAX_OBJECT_FIELD
Maximum length of an object field name.
Definition: sorcery.h:110
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ast_free(a)
Definition: astmm.h:182
Structure for an IP identification matching object.
struct ast_ha * matches
Networks or addresses that should match this.
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ match_to_var_list()

static int match_to_var_list ( const void *  obj,
struct ast_variable **  fields 
)
static

Definition at line 597 of file res_pjsip_endpoint_identifier_ip.c.

References match_to_var_list_append(), ip_identify_match::matches, ast_ha::next, and NULL.

Referenced by load_module().

598 {
599  const struct ip_identify_match *identify = obj;
600  struct ast_variable *head = NULL;
601  struct ast_ha *ha = identify->matches;
602 
603  for (; ha; ha = ha->next) {
604  match_to_var_list_append(&head, ha);
605  }
606 
607  if (head) {
608  *fields = head;
609  }
610 
611  return 0;
612 }
struct ast_ha * next
Definition: acl.h:56
static void match_to_var_list_append(struct ast_variable **head, struct ast_ha *ha)
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
internal representation of ACL entries In principle user applications would have no need for this...
Definition: acl.h:51
Structure for an IP identification matching object.
struct ast_ha * matches
Networks or addresses that should match this.

◆ match_to_var_list_append()

static void match_to_var_list_append ( struct ast_variable **  head,
struct ast_ha ha 
)
static

Definition at line 580 of file res_pjsip_endpoint_identifier_ip.c.

References ast_ha::addr, AST_SENSE_ALLOW, ast_sockaddr_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_variable_list_append, ast_variable_new, MAX_OBJECT_FIELD, ast_ha::netmask, ast_ha::sense, and str.

Referenced by match_to_var_list().

581 {
582  char str[MAX_OBJECT_FIELD];
583  const char *addr;
584 
585  if (ast_sockaddr_port(&ha->addr)) {
587  } else {
589  }
590 
591  snprintf(str, MAX_OBJECT_FIELD, "%s%s/%s", ha->sense == AST_SENSE_ALLOW ? "!" : "",
593 
594  ast_variable_list_append(head, ast_variable_new("match", str, ""));
595 }
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:290
struct ast_sockaddr addr
Definition: acl.h:53
enum ast_acl_sense sense
Definition: acl.h:55
const char * str
Definition: app_jack.c:147
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
struct ast_sockaddr netmask
Definition: acl.h:54
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ast_variable_new(name, value, filename)
#define MAX_OBJECT_FIELD
Maximum length of an object field name.
Definition: sorcery.h:110
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
#define ast_variable_list_append(head, new_var)

◆ my_cli_traverse_objects()

static char* my_cli_traverse_objects ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 816 of file res_pjsip_endpoint_identifier_ip.c.

References ast_sip_cli_traverse_objects().

818 {
819  return ast_sip_cli_traverse_objects(e, cmd, a);
820 }
char * ast_sip_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: pjsip_cli.c:109

◆ reload_module()

static int reload_module ( void  )
static

Definition at line 880 of file res_pjsip_endpoint_identifier_ip.c.

References ast_sip_get_sorcery(), and ast_sorcery_reload_object().

Referenced by unload_module().

881 {
883 
884  return 0;
885 }
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
void ast_sorcery_reload_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to reload persistent objects.
Definition: sorcery.c:1442

◆ send_identify_ami_event()

static int send_identify_ami_event ( void *  obj,
void *  arg,
void *  data,
int  flags 
)
static

Definition at line 620 of file res_pjsip_endpoint_identifier_ip.c.

References ast_free, ast_sip_create_ami_event(), ast_str_append(), ast_str_buffer(), astman_append(), buf, CMP_STOP, ast_sip_ami::count, ip_identify_match::endpoint_name, ast_sip_ami::s, and sip_identify_to_ami().

Referenced by format_ami_endpoint_identify().

621 {
622  struct ip_identify_match *identify = obj;
623  const char *endpoint_name = arg;
624  struct ast_sip_ami *ami = data;
625  struct ast_str *buf;
626 
627  /* Build AMI event */
628  buf = ast_sip_create_ami_event("IdentifyDetail", ami);
629  if (!buf) {
630  return CMP_STOP;
631  }
632  if (sip_identify_to_ami(identify, &buf)) {
633  ast_free(buf);
634  return CMP_STOP;
635  }
636  ast_str_append(&buf, 0, "EndpointName: %s\r\n", endpoint_name);
637 
638  /* Send AMI event */
639  astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
640  ++ami->count;
641 
642  ast_free(buf);
643  return 0;
644 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3080
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
AMI variable container.
Definition: res_pjsip.h:2737
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
struct mansession * s
Definition: res_pjsip.h:2739
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ast_free(a)
Definition: astmm.h:182
struct ast_str * ast_sip_create_ami_event(const char *event, struct ast_sip_ami *ami)
Creates a string to store AMI event data in.
const ast_string_field endpoint_name
Structure for an IP identification matching object.
static int sip_identify_to_ami(const struct ip_identify_match *identify, struct ast_str **buf)

◆ sip_identify_to_ami()

static int sip_identify_to_ami ( const struct ip_identify_match identify,
struct ast_str **  buf 
)
static

Definition at line 614 of file res_pjsip_endpoint_identifier_ip.c.

References ast_sip_sorcery_object_to_ami().

Referenced by send_identify_ami_event().

616 {
617  return ast_sip_sorcery_object_to_ami(identify, buf);
618 }
int ast_sip_sorcery_object_to_ami(const void *obj, struct ast_str **buf)
Converts a sorcery object to a string of object properties.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 887 of file res_pjsip_endpoint_identifier_ip.c.

References ARRAY_LEN, ast_cli_unregister_multiple(), AST_MODFLAG_LOAD_ORDER, AST_MODPRI_CHANNEL_DEPEND, AST_MODULE_INFO(), AST_MODULE_SUPPORT_CORE, ast_sip_unregister_cli_formatter(), ast_sip_unregister_endpoint_formatter(), ast_sip_unregister_endpoint_identifier(), ASTERISK_GPL_KEY, load_module(), reload(), and reload_module().

888 {
894 
895  return 0;
896 }
static struct ast_cli_entry cli_identify[]
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
void ast_sip_unregister_endpoint_formatter(struct ast_sip_endpoint_formatter *obj)
Unregister an endpoint formatter.
Definition: res_pjsip.c:3685
static struct ast_sip_endpoint_identifier ip_identifier
static struct ast_sip_endpoint_identifier header_identifier
static struct ast_sip_cli_formatter_entry * cli_formatter
int ast_sip_unregister_cli_formatter(struct ast_sip_cli_formatter_entry *formatter)
Unregisters a CLI formatter.
Definition: pjsip_cli.c:326
struct ast_sip_endpoint_formatter endpoint_identify_formatter
void ast_sip_unregister_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)
Unregister a SIP endpoint identifier.
Definition: res_pjsip.c:3513

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP IP endpoint identifier" , .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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .reload = reload_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND - 4, .requires = "res_pjsip", }
static

Definition at line 905 of file res_pjsip_endpoint_identifier_ip.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 905 of file res_pjsip_endpoint_identifier_ip.c.

◆ cli_formatter

struct ast_sip_cli_formatter_entry* cli_formatter
static

Definition at line 839 of file res_pjsip_endpoint_identifier_ip.c.

◆ cli_identify

struct ast_cli_entry cli_identify[]
static

Definition at line 822 of file res_pjsip_endpoint_identifier_ip.c.

◆ endpoint_identify_formatter

struct ast_sip_endpoint_formatter endpoint_identify_formatter
Initial value:
= {
}
static int format_ami_endpoint_identify(const struct ast_sip_endpoint *endpoint, struct ast_sip_ami *ami)

Definition at line 671 of file res_pjsip_endpoint_identifier_ip.c.

◆ header_identifier

struct ast_sip_endpoint_identifier header_identifier
static
Initial value:
= {
.identify_endpoint = header_identify,
}
static struct ast_sip_endpoint * header_identify(pjsip_rx_data *rdata)

Definition at line 317 of file res_pjsip_endpoint_identifier_ip.c.

◆ ip_identifier

struct ast_sip_endpoint_identifier ip_identifier
static
Initial value:
= {
.identify_endpoint = ip_identify,
}
static struct ast_sip_endpoint * ip_identify(pjsip_rx_data *rdata)

Definition at line 308 of file res_pjsip_endpoint_identifier_ip.c.