Asterisk - The Open Source Telephony Project GIT-master-f36a736
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 struct ast_sip_endpointrequest_identify (pjsip_rx_data *rdata)
 
static int request_identify_match_check (void *obj, void *arg, int flags)
 Comparator function for matching an object by request URI. More...
 
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 = AST_BUILDOPT_SUM, .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
 
static struct ast_sip_endpoint_identifier request_identifier
 

Macro Definition Documentation

◆ HOSTS_BUCKETS

#define HOSTS_BUCKETS   53

The number of buckets for storing hosts for resolution.

Definition at line 136 of file res_pjsip_endpoint_identifier_ip.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1009 of file res_pjsip_endpoint_identifier_ip.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1009 of file res_pjsip_endpoint_identifier_ip.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1009 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 792 of file res_pjsip_endpoint_identifier_ip.c.

793{
795 struct ao2_container *s_container;
796
798 if (!container) {
799 return NULL;
800 }
801
804 if (!s_container) {
805 return NULL;
806 }
807
808 if (ao2_container_dup(s_container, container, 0)) {
809 ao2_ref(s_container, -1);
810 return NULL;
811 }
812
813 return s_container;
814}
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.
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
struct ao2_container * container
Definition: res_fax.c:501
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
#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:1954
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
Definition: sorcery.c:2464
int ast_sorcery_object_id_sort(const void *obj, const void *arg, int flags)
ao2 object sorter based on sorcery id.
Definition: sorcery.c:2440
Generic container type.
#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

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, RAII_VAR, and regex().

Referenced by load_module().

◆ cli_iterator()

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

Definition at line 769 of file res_pjsip_endpoint_identifier_ip.c.

770{
771 const struct ast_sip_endpoint *endpoint = container;
772 struct ao2_container *identifies;
773
774 struct ast_variable fields = {
775 .name = "endpoint",
776 .value = ast_sorcery_object_get_id(endpoint),
777 .next = NULL,
778 };
779
780 identifies = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "identify",
782 if (!identifies) {
783 return -1;
784 }
785
786 ao2_callback(identifies, OBJ_NODATA, callback, args);
787 ao2_cleanup(identifies);
788
789 return 0;
790}
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
@ OBJ_NODATA
Definition: astobj2.h:1044
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2317
@ AST_RETRIEVE_FLAG_MULTIPLE
Return all matching objects.
Definition: sorcery.h:120
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
An entity with which Asterisk communicates.
Definition: res_pjsip.h:958
Structure for variables, used for configurations and for channel variables.
const char * args

References ao2_callback, ao2_cleanup, args, 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().

◆ cli_print_body()

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

Definition at line 848 of file res_pjsip_endpoint_identifier_ip.c.

849{
851 struct ip_identify_match *ident = obj;
852 struct ast_sip_cli_context *context = arg;
853 struct ast_ha *match;
854 int indent;
855
856 ast_assert(context->output_buffer != NULL);
857
858 ast_str_append(&context->output_buffer, 0, "%*s: %s/%s\n",
859 CLI_INDENT_TO_SPACES(context->indent_level), "Identify",
861
862 if (context->recurse) {
863 context->indent_level++;
864 indent = CLI_INDENT_TO_SPACES(context->indent_level);
865
866 for (match = ident->matches; match; match = match->next) {
867 const char *addr;
868
869 if (ast_sockaddr_port(&match->addr)) {
871 } else {
873 }
874
875 ast_str_append(&context->output_buffer, 0, "%*s: %s%s/%d\n",
876 indent,
877 "Match",
878 match->sense == AST_SENSE_ALLOW ? "!" : "",
879 addr, ast_sockaddr_cidr_bits(&match->netmask));
880 }
881
882 if (!ast_strlen_zero(ident->match_header)) {
883 ast_str_append(&context->output_buffer, 0, "%*s: %s\n",
884 indent,
885 "Header",
886 ident->match_header);
887 }
888
889 if (!ast_strlen_zero(ident->match_request_uri)) {
890 ast_str_append(&context->output_buffer, 0, "%*s: %s\n",
891 indent,
892 "RequestURI",
893 ident->match_request_uri);
894 }
895
896 context->indent_level--;
897
898 if (context->indent_level == 0) {
899 ast_str_append(&context->output_buffer, 0, "\n");
900 }
901 }
902
903 if (context->show_details
904 || (context->show_details_only_level_0 && context->indent_level == 0)) {
905 ast_str_append(&context->output_buffer, 0, "\n");
907 }
908
909 return 0;
910}
@ AST_SENSE_ALLOW
Definition: acl.h:38
const char * str
Definition: app_jack.c:147
#define ast_free(a)
Definition: astmm.h:180
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:2362
int ast_sockaddr_cidr_bits(const struct ast_sockaddr *sa)
Count the 1 bits in a netmask.
Definition: netsock2.c:130
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:517
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:286
int ast_sip_cli_print_sorcery_objectset(void *obj, void *arg, int flags)
Prints a sorcery object's ast_variable list.
Definition: pjsip_cli.c:36
#define CLI_INDENT_TO_SPACES(x)
Definition: res_pjsip_cli.h:29
#define MAX_OBJECT_FIELD
Maximum length of an object field name.
Definition: sorcery.h:110
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:1139
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
internal representation of ACL entries In principle user applications would have no need for this,...
Definition: acl.h:51
struct ast_sockaddr addr
Definition: acl.h:53
CLI Formatter Context passed to all formatters.
Definition: res_pjsip_cli.h:34
Support for dynamic strings.
Definition: strings.h:623
Structure for an IP identification matching object.
const ast_string_field match_header
struct ast_ha * matches
Networks or addresses that should match this.
const ast_string_field match_request_uri
const ast_string_field endpoint_name
#define ast_assert(a)
Definition: utils.h:739

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, voicemailpwcheck::context, ip_identify_match::endpoint_name, match(), ip_identify_match::match_header, ip_identify_match::match_request_uri, ip_identify_match::matches, MAX_OBJECT_FIELD, NULL, RAII_VAR, and str.

Referenced by load_module().

◆ cli_print_header()

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

Definition at line 821 of file res_pjsip_endpoint_identifier_ip.c.

822{
823 struct ast_sip_cli_context *context = arg;
824 int indent = CLI_INDENT_TO_SPACES(context->indent_level);
825 int filler = CLI_MAX_WIDTH - indent - 22;
826
827 ast_assert(context->output_buffer != NULL);
828
829 ast_str_append(&context->output_buffer, 0,
830 "%*s: <Identify/Endpoint%*.*s>\n",
831 indent, "Identify", filler, filler, CLI_HEADER_FILLER);
832
833 if (context->recurse) {
834 context->indent_level++;
835 indent = CLI_INDENT_TO_SPACES(context->indent_level);
836 filler = CLI_LAST_TABSTOP - indent - 24;
837
838 ast_str_append(&context->output_buffer, 0,
839 "%*s: <criteria%*.*s>\n",
840 indent, "Match", filler, filler, CLI_HEADER_FILLER);
841
842 context->indent_level--;
843 }
844
845 return 0;
846}
#define CLI_HEADER_FILLER
Definition: res_pjsip_cli.h:24
#define CLI_MAX_WIDTH
Definition: res_pjsip_cli.h:26
#define CLI_LAST_TABSTOP
Definition: res_pjsip_cli.h:27

References ast_assert, ast_str_append(), CLI_HEADER_FILLER, CLI_INDENT_TO_SPACES, CLI_LAST_TABSTOP, CLI_MAX_WIDTH, voicemailpwcheck::context, and NULL.

Referenced by load_module().

◆ cli_retrieve_by_id()

static void * cli_retrieve_by_id ( const char *  id)
static

Definition at line 816 of file res_pjsip_endpoint_identifier_ip.c.

817{
818 return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "identify", id);
819}
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

References ast_sip_get_sorcery(), and ast_sorcery_retrieve_by_id().

Referenced by load_module().

◆ common_identify()

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

Definition at line 323 of file res_pjsip_endpoint_identifier_ip.c.

324{
325 RAII_VAR(struct ao2_container *, candidates, NULL, ao2_cleanup);
326 struct ip_identify_match *match;
327 struct ast_sip_endpoint *endpoint;
328
329 /* If no possibilities exist return early to save some time */
330 candidates = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "identify",
332 if (!candidates || !ao2_container_count(candidates)) {
333 ast_debug(3, "No identify sections to match against\n");
334 return NULL;
335 }
336
337 match = ao2_callback(candidates, 0, identify_match_cb, arg);
338 if (!match) {
339 return NULL;
340 }
341
342 endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
343 match->endpoint_name);
344 if (endpoint) {
345 ast_debug(3, "Identify '%s' SIP message matched to endpoint %s\n",
346 ast_sorcery_object_get_id(match), match->endpoint_name);
347 } else {
348 ast_log(LOG_WARNING, "Identify '%s' points to endpoint '%s' but endpoint could not be found\n",
349 ast_sorcery_object_get_id(match), match->endpoint_name);
350 }
351
352 ao2_ref(match, -1);
353 return endpoint;
354}
#define ast_log
Definition: astobj2.c:42
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_WARNING
@ AST_RETRIEVE_FLAG_ALL
Perform no matching, return all objects.
Definition: sorcery.h:123

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(), LOG_WARNING, match(), NULL, and RAII_VAR.

Referenced by header_identify(), ip_identify(), and request_identify().

◆ 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 740 of file res_pjsip_endpoint_identifier_ip.c.

742{
743 struct ao2_container *identifies;
744 struct ast_variable fields = {
745 .name = "endpoint",
746 .value = ast_sorcery_object_get_id(endpoint),
747 };
748
749 identifies = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "identify",
751 if (!identifies) {
752 return -1;
753 }
754
755 /* Build and send any found identify object's AMI IdentifyDetail event. */
758 (void *) ast_sorcery_object_get_id(endpoint),
759 ami);
760
761 ao2_ref(identifies, -1);
762 return 0;
763}
#define ao2_callback_data(container, flags, cb_fn, arg, data)
Definition: astobj2.h:1723
@ OBJ_MULTIPLE
Definition: astobj2.h:1049
static int send_identify_ami_event(void *obj, void *arg, void *data, int flags)

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().

◆ header_identify()

static struct ast_sip_endpoint * header_identify ( pjsip_rx_data *  rdata)
static

Definition at line 370 of file res_pjsip_endpoint_identifier_ip.c.

371{
373}
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.

References common_identify(), and header_identify_match_check().

◆ 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 201 of file res_pjsip_endpoint_identifier_ip.c.

202{
203 struct ip_identify_match *identify = obj;
204 struct pjsip_rx_data *rdata = arg;
205 pjsip_hdr *header;
206 pj_str_t pj_header_name;
207 int header_present;
208
209 if (ast_strlen_zero(identify->match_header)) {
210 return 0;
211 }
212
213 pj_header_name = pj_str((void *) identify->match_header_name);
214
215 /* Check all headers of the given name for a match. */
216 header_present = 0;
217 for (header = NULL;
218 (header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &pj_header_name, header));
219 header = header->next) {
220 char *pos;
221 int len;
222 char buf[PATH_MAX];
223
224 header_present = 1;
225
226 /* Print header line to buf */
227 len = pjsip_hdr_print_on(header, buf, sizeof(buf) - 1);
228 if (len < 0) {
229 /* Buffer not large enough or no header vptr! */
230 ast_assert(0);
231 continue;
232 }
233 buf[len] = '\0';
234
235 /* Remove header name from pj_buf and trim blanks. */
236 pos = strchr(buf, ':');
237 if (!pos) {
238 /* No header name? Bug in PJPROJECT if so. */
239 ast_assert(0);
240 continue;
241 }
242 pos = ast_strip(pos + 1);
243
244 /* Does header value match what we are looking for? */
245 if (identify->is_header_regex) {
246 if (!regexec(&identify->regex_header_buf, pos, 0, NULL, 0)) {
247 return CMP_MATCH;
248 }
249 } else if (!strcmp(identify->match_header_value, pos)) {
250 return CMP_MATCH;
251 }
252
253 ast_debug(3, "Identify '%s': SIP message has '%s' header but value '%s' does not match '%s'.\n",
255 identify->match_header_name,
256 pos,
257 identify->match_header_value);
258 }
259 if (!header_present) {
260 ast_debug(3, "Identify '%s': SIP message does not have '%s' header.\n",
262 identify->match_header_name);
263 }
264 return 0;
265}
#define PATH_MAX
Definition: asterisk.h:40
@ CMP_MATCH
Definition: astobj2.h:1027
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
struct header * next
const ast_string_field match_header_value
const ast_string_field match_header_name

References ast_assert, ast_debug, ast_sorcery_object_get_id(), ast_strip(), ast_strlen_zero(), buf, CMP_MATCH, ip_identify_match::is_header_regex, len(), ip_identify_match::match_header, ip_identify_match::match_header_name, ip_identify_match::match_header_value, header::next, NULL, PATH_MAX, and ip_identify_match::regex_header_buf.

Referenced by header_identify().

◆ ip_identify()

static struct ast_sip_endpoint * ip_identify ( pjsip_rx_data *  rdata)
static

Definition at line 356 of file res_pjsip_endpoint_identifier_ip.c.

357{
358 struct ast_sockaddr addr = { { 0, } };
359
360 ast_sockaddr_parse(&addr, rdata->pkt_info.src_name, PARSE_PORT_FORBID);
361 ast_sockaddr_set_port(&addr, rdata->pkt_info.src_port);
362
364}
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:532
static int ip_identify_match_check(void *obj, void *arg, int flags)
Comparator function for matching an object by IP address.
Socket address structure.
Definition: netsock2.h:97

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

◆ ip_identify_alloc()

static void * ip_identify_alloc ( const char *  name)
static

Allocator function for a matching object.

Definition at line 188 of file res_pjsip_endpoint_identifier_ip.c.

189{
190 struct ip_identify_match *identify = ast_sorcery_generic_alloc(sizeof(*identify), ip_identify_destroy);
191
192 if (!identify || ast_string_field_init(identify, 256)) {
193 ao2_cleanup(identify);
194 return NULL;
195 }
196
197 return identify;
198}
static void ip_identify_destroy(void *obj)
Destructor function for a matching object.
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
Definition: sorcery.c:1728
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359

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

Referenced by load_module().

◆ ip_identify_apply()

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

Apply handler for identify type.

Definition at line 510 of file res_pjsip_endpoint_identifier_ip.c.

511{
512 struct ip_identify_match *identify = obj;
513 char *current_string;
514 struct ao2_iterator i;
515
516 /* Validate the identify object configuration */
517 if (ast_strlen_zero(identify->endpoint_name)) {
518 ast_log(LOG_ERROR, "Identify '%s' missing required endpoint name.\n",
519 ast_sorcery_object_get_id(identify));
520 return -1;
521 }
522 if (ast_strlen_zero(identify->match_header) /* No header to match */
523 && ast_strlen_zero(identify->match_request_uri) /* and no request to match */
524 /* and no static IP addresses with a mask */
525 && !identify->matches
526 /* and no addresses to resolve */
527 && (!identify->hosts || !ao2_container_count(identify->hosts))) {
528 ast_log(LOG_ERROR, "Identify '%s' is not configured to match anything.\n",
529 ast_sorcery_object_get_id(identify));
530 return -1;
531 }
532
533 if (!ast_strlen_zero(identify->match_header)) {
534 char *c_header;
535 char *c_value;
536 int len;
537
538 /* Split the header name and value */
539 c_header = ast_strdupa(identify->match_header);
540 c_value = strchr(c_header, ':');
541 if (!c_value) {
542 ast_log(LOG_ERROR, "Identify '%s' missing ':' separator in match_header '%s'.\n",
543 ast_sorcery_object_get_id(identify), identify->match_header);
544 return -1;
545 }
546 *c_value = '\0';
547 c_value = ast_strip(c_value + 1);
548 c_header = ast_strip(c_header);
549
550 if (ast_strlen_zero(c_header)) {
551 ast_log(LOG_ERROR, "Identify '%s' has no SIP header to match in match_header '%s'.\n",
552 ast_sorcery_object_get_id(identify), identify->match_header);
553 return -1;
554 }
555
556 if (!strcmp(c_value, "//")) {
557 /* An empty regex is the same as an empty literal string. */
558 c_value = "";
559 }
560
561 if (ast_string_field_set(identify, match_header_name, c_header)
562 || ast_string_field_set(identify, match_header_value, c_value)) {
563 return -1;
564 }
565
566 len = strlen(c_value);
567 if (2 < len && c_value[0] == '/' && c_value[len - 1] == '/') {
568 /* Make "/regex/" into "regex" */
569 c_value[len - 1] = '\0';
570 ++c_value;
571
572 if (regcomp(&identify->regex_header_buf, c_value, REG_EXTENDED | REG_NOSUB)) {
573 ast_log(LOG_ERROR, "Identify '%s' failed to compile match_request_uri regex '%s'.\n",
574 ast_sorcery_object_get_id(identify), c_value);
575 return -1;
576 }
577 identify->is_header_regex = 1;
578 }
579 }
580
581 if (!ast_strlen_zero(identify->match_request_uri)) {
582 char *c_string;
583 int len;
584
585 len = strlen(identify->match_request_uri);
586 c_string = ast_strdupa(identify->match_request_uri);
587
588 if (!strcmp(c_string, "//")) {
589 /* An empty regex is the same as an empty literal string. */
590 c_string = "";
591 }
592
593 if (2 < len && c_string[0] == '/' && c_string[len - 1] == '/') {
594 /* Make "/regex/" into "regex" */
595 c_string[len - 1] = '\0';
596 ++c_string;
597
598 if (regcomp(&identify->regex_request_uri_buf, c_string, REG_EXTENDED | REG_NOSUB)) {
599 ast_log(LOG_ERROR, "Identify '%s' failed to compile match_header regex '%s'.\n",
600 ast_sorcery_object_get_id(identify), c_string);
601 return -1;
602 }
603 identify->is_request_uri_regex = 1;
604 }
605 }
606
607 if (!identify->hosts) {
608 /* No match addresses to resolve */
609 return 0;
610 }
611
612 /* Hosts can produce dynamic content, so mark the identify as such */
614
615 /* Resolve the match addresses now */
616 i = ao2_iterator_init(identify->hosts, 0);
617 while ((current_string = ao2_iterator_next(&i))) {
618 int results = 0;
619 char *colon = strrchr(current_string, ':');
620
621 /* We skip SRV lookup if a colon is present, assuming a port was specified */
622 if (!colon) {
623 /* No port, and we know this is not an IP address, so perform SRV resolution on it */
624 if (identify->srv_lookups) {
625 results = ip_identify_match_srv_lookup(identify, "_sip._udp", current_string,
626 results);
627 if (results != -1) {
628 results = ip_identify_match_srv_lookup(identify, "_sip._tcp",
629 current_string, results);
630 }
631 if (results != -1) {
632 results = ip_identify_match_srv_lookup(identify, "_sips._tcp",
633 current_string, results);
634 }
635 }
636 }
637
638 /* If SRV fails fall back to a normal lookup on the host itself */
639 if (!results) {
640 results = ip_identify_match_host_lookup(identify, current_string);
641 }
642
643 if (results == 0) {
644 ast_log(LOG_WARNING, "Identify '%s' provided address '%s' did not resolve to any address\n",
645 ast_sorcery_object_get_id(identify), current_string);
646 } else if (results == -1) {
647 ast_log(LOG_ERROR, "Identify '%s' failed when adding resolution results of '%s'\n",
648 ast_sorcery_object_get_id(identify), current_string);
649 ao2_ref(current_string, -1);
651 return -1;
652 }
653
654 ao2_ref(current_string, -1);
655 }
657
658 ao2_ref(identify->hosts, -1);
659 identify->hosts = NULL;
660
661 return 0;
662}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define LOG_ERROR
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.
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.
void ast_sorcery_object_set_has_dynamic_contents(const void *object)
Set the dynamic contents flag on a sorcery object.
Definition: sorcery.c:2384
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
struct ao2_container * hosts
Hosts to be resolved when applying configuration.
unsigned int srv_lookups
Perform SRV resolution of hostnames.

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_header_regex, ip_identify_match::is_request_uri_regex, len(), LOG_ERROR, LOG_WARNING, ip_identify_match::match_header, ip_identify_match::match_request_uri, ip_identify_match::matches, NULL, ip_identify_match::regex_header_buf, ip_identify_match::regex_request_uri_buf, and ip_identify_match::srv_lookups.

Referenced by load_module().

◆ ip_identify_destroy()

static void ip_identify_destroy ( void *  obj)
static

Destructor function for a matching object.

Definition at line 172 of file res_pjsip_endpoint_identifier_ip.c.

173{
174 struct ip_identify_match *identify = obj;
175
177 ast_free_ha(identify->matches);
178 ao2_cleanup(identify->hosts);
179 if (identify->is_header_regex) {
180 regfree(&identify->regex_header_buf);
181 }
182 if (identify->is_request_uri_regex) {
183 regfree(&identify->regex_request_uri_buf);
184 }
185}
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
Definition: acl.c:222
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374

References ao2_cleanup, ast_free_ha(), ast_string_field_free_memory, ip_identify_match::hosts, ip_identify_match::is_header_regex, ip_identify_match::is_request_uri_regex, ip_identify_match::matches, ip_identify_match::regex_header_buf, and ip_identify_match::regex_request_uri_buf.

Referenced by ip_identify_alloc().

◆ 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 303 of file res_pjsip_endpoint_identifier_ip.c.

304{
305 struct ip_identify_match *identify = obj;
306 struct ast_sockaddr *addr = arg;
307 int sense;
308
309 sense = ast_apply_ha(identify->matches, addr);
310 if (sense != AST_SENSE_ALLOW) {
311 ast_debug(3, "Source address %s matches identify '%s'\n",
313 ast_sorcery_object_get_id(identify));
314 return CMP_MATCH;
315 } else {
316 ast_debug(3, "Source address %s does not match identify '%s'\n",
318 ast_sorcery_object_get_id(identify));
319 return 0;
320 }
321}
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:807

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().

◆ 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 454 of file res_pjsip_endpoint_identifier_ip.c.

455{
456 struct ip_identify_match *identify = obj;
457 char *input_string = ast_strdupa(var->value);
458 char *current_string;
459
460 if (ast_strlen_zero(var->value)) {
461 return 0;
462 }
463
464 while ((current_string = ast_strip(strsep(&input_string, ",")))) {
465 char *mask;
466 struct ast_sockaddr address;
467 int error = 0;
468
469 if (ast_strlen_zero(current_string)) {
470 continue;
471 }
472
473 mask = strrchr(current_string, '/');
474
475 /* If it looks like a netmask is present, or we can immediately parse as an IP,
476 * hand things off to the ACL */
477 if (mask || ast_sockaddr_parse(&address, current_string, 0)) {
478 identify->matches = ast_append_ha_with_port("d", current_string, identify->matches, &error);
479
480 if (!identify->matches || error) {
481 ast_log(LOG_ERROR, "Failed to add address '%s' to ip endpoint identifier '%s'\n",
482 current_string, ast_sorcery_object_get_id(obj));
483 return -1;
484 }
485
486 continue;
487 }
488
489 if (!identify->hosts) {
491 if (!identify->hosts) {
492 ast_log(LOG_ERROR, "Failed to create container to store hosts on ip endpoint identifier '%s'\n",
494 return -1;
495 }
496 }
497
498 error = ast_str_container_add(identify->hosts, current_string);
499 if (error) {
500 ast_log(LOG_ERROR, "Failed to store host '%s' for resolution on ip endpoint identifier '%s'\n",
501 current_string, ast_sorcery_object_get_id(obj));
502 return -1;
503 }
504 }
505
506 return 0;
507}
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:717
#define var
Definition: ast_expr2f.c:605
char * address
Definition: f2c.h:59
char * strsep(char **str, const char *delims)
#define HOSTS_BUCKETS
The number of buckets for storing hosts for resolution.
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:200
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:205
int error(const char *format,...)
Definition: utils/frame.c:999

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 var.

Referenced by load_module().

◆ 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 389 of file res_pjsip_endpoint_identifier_ip.c.

390{
391 struct ast_sockaddr *addrs;
392 int num_addrs = 0, error = 0, i;
393 int results = 0;
394
395 num_addrs = ast_sockaddr_resolve(&addrs, host, 0, AST_AF_UNSPEC);
396 if (!num_addrs) {
397 return -1;
398 }
399
400 for (i = 0; i < num_addrs; ++i) {
401 /* Check if the address is already in the list, if so don't add it again */
402 if (identify->matches && (ast_apply_ha(identify->matches, &addrs[i]) != AST_SENSE_ALLOW)) {
403 continue;
404 }
405
406 /* We deny what we actually want to match because there is an implicit permit all rule for ACLs */
407 identify->matches = ast_append_ha_with_port("d", ast_sockaddr_stringify(&addrs[i]), identify->matches, &error);
408
409 if (!identify->matches || error) {
410 results = -1;
411 break;
412 }
413
414 results += 1;
415 }
416
417 ast_free(addrs);
418
419 return results;
420}
@ AST_AF_UNSPEC
Definition: netsock2.h:54
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

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().

◆ 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 423 of file res_pjsip_endpoint_identifier_ip.c.

424{
425 char service[NI_MAXHOST];
426 struct srv_context *context = NULL;
427 int srv_ret;
428 const char *srvhost;
429 unsigned short srvport;
430
431 snprintf(service, sizeof(service), "%s.%s", prefix, host);
432
433 while (!(srv_ret = ast_srv_lookup(&context, service, &srvhost, &srvport))) {
434 int hosts;
435
436 /* In the case of the SRV lookup we don't care if it fails, we will output a log message
437 * when we fallback to a normal lookup.
438 */
439 hosts = ip_identify_match_host_lookup(identify, srvhost);
440 if (hosts == -1) {
441 results = -1;
442 break;
443 } else {
444 results += hosts;
445 }
446 }
447
449
450 return results;
451}
enum ast_cc_service_type service
Definition: ccss.c:383
static char prefix[MAX_PREFIX]
Definition: http.c:144
void ast_srv_cleanup(struct srv_context **context)
Cleanup resources associated with ast_srv_lookup.
Definition: srv.c:248
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

References ast_srv_cleanup(), ast_srv_lookup(), voicemailpwcheck::context, ip_identify_match_host_lookup(), NULL, prefix, and service.

Referenced by ip_identify_apply().

◆ load_module()

static int load_module ( void  )
static

Definition at line 942 of file res_pjsip_endpoint_identifier_ip.c.

943{
944 ast_sorcery_apply_config(ast_sip_get_sorcery(), "res_pjsip_endpoint_identifier_ip");
945 ast_sorcery_apply_default(ast_sip_get_sorcery(), "identify", "config", "pjsip.conf,criteria=type=identify");
946
949 }
950
951 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "type", "", OPT_NOOP_T, 0, 0);
952 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "endpoint", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, endpoint_name));
954 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "match_header", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, match_header));
955 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "match_request_uri", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, match_request_uri));
956 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "srv_lookups", "yes", OPT_BOOL_T, 1, FLDSET(struct ip_identify_match, srv_lookups));
958
963
965 if (!cli_formatter) {
966 ast_log(LOG_ERROR, "Unable to allocate memory for cli formatter\n");
968 }
969 cli_formatter->name = "identify";
976
979
981}
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
@ OPT_NOOP_T
Type for a default handler that should do nothing.
@ OPT_BOOL_T
Type for default option handler for bools (ast_true/ast_false)
@ OPT_STRINGFIELD_T
Type for default option handler for stringfields.
@ 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
void ast_sip_register_endpoint_formatter(struct ast_sip_endpoint_formatter *obj)
Register an endpoint formatter.
Definition: res_pjsip.c:481
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:233
int ast_sip_register_cli_formatter(struct ast_sip_cli_formatter_entry *formatter)
Registers a CLI formatter.
Definition: pjsip_cli.c:310
static int cli_print_header(void *obj, void *arg, int flags)
static int cli_iterator(void *container, ao2_callback_fn callback, void *args)
static void * ip_identify_alloc(const char *name)
Allocator function for a matching object.
static struct ast_sip_endpoint_identifier request_identifier
static int ip_identify_apply(const struct ast_sorcery *sorcery, void *obj)
Apply handler for identify type.
static int ip_identify_match_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom handler for match field.
static struct ast_sip_endpoint_identifier header_identifier
static void * cli_retrieve_by_id(const char *id)
static struct ast_cli_entry cli_identify[]
static struct ao2_container * cli_get_container(const char *regex)
struct ast_sip_endpoint_formatter endpoint_identify_formatter
static int cli_print_body(void *obj, void *arg, int flags)
static struct ast_sip_cli_formatter_entry * cli_formatter
static struct ast_sip_endpoint_identifier ip_identifier
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)
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
Definition: sorcery.h:837
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
#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 ast_sorcery_apply_config(sorcery, name)
Definition: sorcery.h:455
#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object.
Definition: sorcery.h:955
#define ast_sorcery_apply_default(sorcery, type, name, data)
Definition: sorcery.h:476
CLI Formatter Registry Entry.
Definition: res_pjsip_cli.h:52
int(* iterate)(void *container, ao2_callback_fn callback, void *args)
Definition: res_pjsip_cli.h:66
ao2_callback_fn * print_header
Definition: res_pjsip_cli.h:60
void *(* retrieve_by_id)(const char *id)
Definition: res_pjsip_cli.h:68
const char *(* get_id)(const void *obj)
Definition: res_pjsip_cli.h:70
const char * name
Definition: res_pjsip_cli.h:58
ao2_callback_fn * print_body
Definition: res_pjsip_cli.h:62
struct ao2_container *(* get_container)(const char *regex)
Definition: res_pjsip_cli.h:64
#define ARRAY_LEN(a)
Definition: utils.h:666

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_formatter, cli_get_container(), cli_identify, cli_iterator(), cli_print_body(), cli_print_header(), cli_retrieve_by_id(), endpoint_identify_formatter, FLDSET, ast_sip_cli_formatter_entry::get_container, ast_sip_cli_formatter_entry::get_id, header_identifier, ip_identifier, ip_identify_alloc(), ip_identify_apply(), ip_identify_match_handler(), ast_sip_cli_formatter_entry::iterate, LOG_ERROR, 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, request_identifier, ast_sip_cli_formatter_entry::retrieve_by_id, and STRFLDSET.

◆ match_to_str()

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

Definition at line 664 of file res_pjsip_endpoint_identifier_ip.c.

665{
667 const struct ip_identify_match *identify = obj;
668
669 ast_ha_join(identify->matches, &str);
671 return 0;
672}
void ast_ha_join(const struct ast_ha *ha, struct ast_str **buf)
Convert HAs to a comma separated string value.
Definition: acl.c:722
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761

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

Referenced by load_module().

◆ match_to_var_list()

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

Definition at line 691 of file res_pjsip_endpoint_identifier_ip.c.

692{
693 const struct ip_identify_match *identify = obj;
694 struct ast_variable *head = NULL;
695 struct ast_ha *ha = identify->matches;
696
697 for (; ha; ha = ha->next) {
698 match_to_var_list_append(&head, ha);
699 }
700
701 if (head) {
702 *fields = head;
703 }
704
705 return 0;
706}
static void match_to_var_list_append(struct ast_variable **head, struct ast_ha *ha)
struct ast_ha * next
Definition: acl.h:56

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

Referenced by load_module().

◆ match_to_var_list_append()

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

Definition at line 674 of file res_pjsip_endpoint_identifier_ip.c.

675{
676 char str[MAX_OBJECT_FIELD];
677 const char *addr;
678
679 if (ast_sockaddr_port(&ha->addr)) {
681 } else {
683 }
684
685 snprintf(str, MAX_OBJECT_FIELD, "%s%s/%s", ha->sense == AST_SENSE_ALLOW ? "!" : "",
687
688 ast_variable_list_append(head, ast_variable_new("match", str, ""));
689}
#define ast_variable_new(name, value, filename)
#define ast_variable_list_append(head, new_var)
struct ast_sockaddr netmask
Definition: acl.h:54
enum ast_acl_sense sense
Definition: acl.h:55

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().

◆ 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 917 of file res_pjsip_endpoint_identifier_ip.c.

919{
920 return ast_sip_cli_traverse_objects(e, cmd, a);
921}
char * ast_sip_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: pjsip_cli.c:109
static struct test_val a

References a, and ast_sip_cli_traverse_objects().

◆ reload_module()

static int reload_module ( void  )
static

Definition at line 983 of file res_pjsip_endpoint_identifier_ip.c.

984{
986
987 return 0;
988}
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

References ast_sip_get_sorcery(), and ast_sorcery_reload_object().

◆ request_identify()

static struct ast_sip_endpoint * request_identify ( pjsip_rx_data *  rdata)
static

Definition at line 375 of file res_pjsip_endpoint_identifier_ip.c.

376{
378}
static int request_identify_match_check(void *obj, void *arg, int flags)
Comparator function for matching an object by request URI.

References common_identify(), and request_identify_match_check().

◆ request_identify_match_check()

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

Comparator function for matching an object by request URI.

Definition at line 268 of file res_pjsip_endpoint_identifier_ip.c.

269{
270 struct ip_identify_match *identify = obj;
271 struct pjsip_rx_data *rdata = arg;
272 int len;
273 char buf[PJSIP_MAX_URL_SIZE];
274
275 if (ast_strlen_zero(identify->match_request_uri)) {
276 return 0;
277 }
278
279 /* Print request URI to req_buf */
280 len = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, rdata->msg_info.msg->line.req.uri, buf, sizeof(buf) - 1);
281 if (len < 0) {
282 /* Buffer not large enough or no pj uri vptr! */
283 ast_assert(0);
284 } else {
285 /* Terminate the pj_str */
286 buf[len] = '\0';
287 /* Does request URI match what we are looking for? */
288 if (identify->is_request_uri_regex) {
289 if (!regexec(&identify->regex_request_uri_buf, buf, 0, NULL, 0)) {
290 return CMP_MATCH;
291 }
292 } else if (!strcmp(identify->match_request_uri, buf)) {
293 return CMP_MATCH;
294 }
295 ast_debug(3, "Identify '%s': request URI not match '%s' (value='%s').\n",
296 ast_sorcery_object_get_id(identify), identify->match_request_uri, buf);
297 }
298
299 return 0;
300}

References ast_assert, ast_debug, ast_sorcery_object_get_id(), ast_strlen_zero(), buf, CMP_MATCH, ip_identify_match::is_request_uri_regex, len(), ip_identify_match::match_request_uri, NULL, and ip_identify_match::regex_request_uri_buf.

Referenced by request_identify().

◆ send_identify_ami_event()

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

Definition at line 714 of file res_pjsip_endpoint_identifier_ip.c.

715{
716 struct ip_identify_match *identify = obj;
717 const char *endpoint_name = arg;
718 struct ast_sip_ami *ami = data;
719 struct ast_str *buf;
720
721 /* Build AMI event */
722 buf = ast_sip_create_ami_event("IdentifyDetail", ami);
723 if (!buf) {
724 return CMP_STOP;
725 }
726 if (sip_identify_to_ami(identify, &buf)) {
727 ast_free(buf);
728 return CMP_STOP;
729 }
730 ast_str_append(&buf, 0, "EndpointName: %s\r\n", endpoint_name);
731
732 /* Send AMI event */
733 astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
734 ++ami->count;
735
736 ast_free(buf);
737 return 0;
738}
@ CMP_STOP
Definition: astobj2.h:1028
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:1890
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.
static int sip_identify_to_ami(const struct ip_identify_match *identify, struct ast_str **buf)
AMI variable container.
Definition: res_pjsip.h:3046
struct mansession * s
Definition: res_pjsip.h:3048

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().

◆ sip_identify_to_ami()

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

Definition at line 708 of file res_pjsip_endpoint_identifier_ip.c.

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

References ast_sip_sorcery_object_to_ami(), and buf.

Referenced by send_identify_ami_event().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 990 of file res_pjsip_endpoint_identifier_ip.c.

991{
998
999 return 0;
1000}
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
void ast_sip_unregister_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)
Unregister a SIP endpoint identifier.
Definition: res_pjsip.c:315
void ast_sip_unregister_endpoint_formatter(struct ast_sip_endpoint_formatter *obj)
Unregister an endpoint formatter.
Definition: res_pjsip.c:487
int ast_sip_unregister_cli_formatter(struct ast_sip_cli_formatter_entry *formatter)
Unregisters a CLI formatter.
Definition: pjsip_cli.c:326

References ARRAY_LEN, ast_cli_unregister_multiple(), ast_sip_unregister_cli_formatter(), ast_sip_unregister_endpoint_formatter(), ast_sip_unregister_endpoint_identifier(), cli_formatter, cli_identify, endpoint_identify_formatter, header_identifier, ip_identifier, and request_identifier.

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 = AST_BUILDOPT_SUM, .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 1009 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 1009 of file res_pjsip_endpoint_identifier_ip.c.

◆ cli_formatter

struct ast_sip_cli_formatter_entry* cli_formatter
static

Definition at line 940 of file res_pjsip_endpoint_identifier_ip.c.

Referenced by load_module(), and unload_module().

◆ cli_identify

struct ast_cli_entry cli_identify[]
static

Definition at line 923 of file res_pjsip_endpoint_identifier_ip.c.

Referenced by load_module(), and unload_module().

◆ 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 765 of file res_pjsip_endpoint_identifier_ip.c.

Referenced by load_module(), and unload_module().

◆ 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 380 of file res_pjsip_endpoint_identifier_ip.c.

Referenced by load_module(), and unload_module().

◆ 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 366 of file res_pjsip_endpoint_identifier_ip.c.

Referenced by load_module(), and unload_module().

◆ request_identifier

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

Definition at line 384 of file res_pjsip_endpoint_identifier_ip.c.

Referenced by load_module(), and unload_module().