Asterisk - The Open Source Telephony Project GIT-master-27fb039
Loading...
Searching...
No Matches
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.
 

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.
 
static struct ast_sip_endpointip_identify (pjsip_rx_data *rdata)
 
static void * ip_identify_alloc (const char *name)
 Allocator function for a matching object.
 
static int ip_identify_apply (const struct ast_sorcery *sorcery, void *obj)
 Apply handler for identify type.
 
static void ip_identify_destroy (void *obj)
 Destructor function for a matching object.
 
static int ip_identify_match_check (void *obj, void *arg, int flags)
 Comparator function for matching an object by IP address.
 
static int ip_identify_match_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 Custom handler for match field.
 
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 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 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.
 
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 = ASTERISK_GPL_KEY , .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 162 of file res_pjsip_endpoint_identifier_ip.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1035 of file res_pjsip_endpoint_identifier_ip.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1035 of file res_pjsip_endpoint_identifier_ip.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

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

819{
821 struct ao2_container *s_container;
822
824 if (!container) {
825 return NULL;
826 }
827
830 if (!s_container) {
831 return NULL;
832 }
833
834 if (ao2_container_dup(s_container, container, 0)) {
835 ao2_ref(s_container, -1);
836 return NULL;
837 }
838
839 return s_container;
840}
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:603
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:2018
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
Definition sorcery.c:2528
int ast_sorcery_object_id_sort(const void *obj, const void *arg, int flags)
ao2 object sorter based on sorcery id.
Definition sorcery.c:2504
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:981

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

796{
797 const struct ast_sip_endpoint *endpoint = container;
798 struct ao2_container *identifies;
799
800 struct ast_variable fields = {
801 .name = "endpoint",
802 .value = ast_sorcery_object_get_id(endpoint),
803 .next = NULL,
804 };
805
806 identifies = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "identify",
808 if (!identifies) {
809 return -1;
810 }
811
812 ao2_callback(identifies, OBJ_NODATA, callback, args);
813 ao2_cleanup(identifies);
814
815 return 0;
816}
#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
static struct ast_channel * callback(struct ast_channelstorage_instance *driver, ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags)
static struct @519 args
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition sorcery.c:2381
@ 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:1961
An entity with which Asterisk communicates.
Definition res_pjsip.h:1051
Structure for variables, used for configurations and for channel variables.

References ao2_callback, ao2_cleanup, args, AST_RETRIEVE_FLAG_MULTIPLE, ast_sip_get_sorcery(), ast_sorcery_object_get_id(), ast_sorcery_retrieve_by_fields(), callback(), 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 874 of file res_pjsip_endpoint_identifier_ip.c.

875{
877 struct ip_identify_match *ident = obj;
878 struct ast_sip_cli_context *context = arg;
879 struct ast_ha *match;
880 int indent;
881
882 ast_assert(context->output_buffer != NULL);
883
884 ast_str_append(&context->output_buffer, 0, "%*s: %s/%s\n",
885 CLI_INDENT_TO_SPACES(context->indent_level), "Identify",
887
888 if (context->recurse) {
889 context->indent_level++;
890 indent = CLI_INDENT_TO_SPACES(context->indent_level);
891
892 for (match = ident->matches; match; match = match->next) {
893 const char *addr;
894
895 if (ast_sockaddr_port(&match->addr)) {
897 } else {
899 }
900
901 ast_str_append(&context->output_buffer, 0, "%*s: %s%s/%d\n",
902 indent,
903 "Match",
904 match->sense == AST_SENSE_ALLOW ? "!" : "",
906 }
907
908 if (!ast_strlen_zero(ident->match_header)) {
909 ast_str_append(&context->output_buffer, 0, "%*s: %s\n",
910 indent,
911 "Header",
912 ident->match_header);
913 }
914
915 if (!ast_strlen_zero(ident->match_request_uri)) {
916 ast_str_append(&context->output_buffer, 0, "%*s: %s\n",
917 indent,
918 "RequestURI",
919 ident->match_request_uri);
920 }
921
922 context->indent_level--;
923
924 if (context->indent_level == 0) {
925 ast_str_append(&context->output_buffer, 0, "\n");
926 }
927 }
928
929 if (context->show_details
930 || (context->show_details_only_level_0 && context->indent_level == 0)) {
931 ast_str_append(&context->output_buffer, 0, "\n");
932 ast_sip_cli_print_sorcery_objectset(ident, context, 0);
933 }
934
935 return 0;
936}
@ AST_SENSE_ALLOW
Definition acl.h:38
const char * str
Definition app_jack.c:150
#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:2388
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)
#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
struct ast_sockaddr netmask
Definition acl.h:54
CLI Formatter Context passed to all formatters.
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:779

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, 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 847 of file res_pjsip_endpoint_identifier_ip.c.

848{
849 struct ast_sip_cli_context *context = arg;
850 int indent = CLI_INDENT_TO_SPACES(context->indent_level);
851 int filler = CLI_MAX_WIDTH - indent - 22;
852
853 ast_assert(context->output_buffer != NULL);
854
855 ast_str_append(&context->output_buffer, 0,
856 "%*s: <Identify/Endpoint%*.*s>\n",
857 indent, "Identify", filler, filler, CLI_HEADER_FILLER);
858
859 if (context->recurse) {
860 context->indent_level++;
861 indent = CLI_INDENT_TO_SPACES(context->indent_level);
862 filler = CLI_LAST_TABSTOP - indent - 24;
863
864 ast_str_append(&context->output_buffer, 0,
865 "%*s: <criteria%*.*s>\n",
866 indent, "Match", filler, filler, CLI_HEADER_FILLER);
867
868 context->indent_level--;
869 }
870
871 return 0;
872}
#define CLI_HEADER_FILLER
#define CLI_MAX_WIDTH
#define CLI_LAST_TABSTOP

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

Referenced by load_module().

◆ cli_retrieve_by_id()

static void * cli_retrieve_by_id ( const char *  id)
static

Definition at line 842 of file res_pjsip_endpoint_identifier_ip.c.

843{
844 return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "identify", id);
845}
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:1917

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

350{
351 RAII_VAR(struct ao2_container *, candidates, NULL, ao2_cleanup);
352 struct ip_identify_match *match;
353 struct ast_sip_endpoint *endpoint;
354
355 /* If no possibilities exist return early to save some time */
356 candidates = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "identify",
358 if (!candidates || !ao2_container_count(candidates)) {
359 ast_debug(3, "No identify sections to match against\n");
360 return NULL;
361 }
362
363 match = ao2_callback(candidates, 0, identify_match_cb, arg);
364 if (!match) {
365 return NULL;
366 }
367
368 endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
369 match->endpoint_name);
370 if (endpoint) {
371 ast_debug(3, "Identify '%s' SIP message matched to endpoint %s\n",
372 ast_sorcery_object_get_id(match), match->endpoint_name);
373 } else {
374 ast_log(LOG_WARNING, "Identify '%s' points to endpoint '%s' but endpoint could not be found\n",
375 ast_sorcery_object_get_id(match), match->endpoint_name);
376 }
377
378 ao2_ref(match, -1);
379 return endpoint;
380}
#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 766 of file res_pjsip_endpoint_identifier_ip.c.

768{
769 struct ao2_container *identifies;
770 struct ast_variable fields = {
771 .name = "endpoint",
772 .value = ast_sorcery_object_get_id(endpoint),
773 };
774
775 identifies = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "identify",
777 if (!identifies) {
778 return -1;
779 }
780
781 /* Build and send any found identify object's AMI IdentifyDetail event. */
784 (void *) ast_sorcery_object_get_id(endpoint),
785 ami);
786
787 ao2_ref(identifies, -1);
788 return 0;
789}
#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 396 of file res_pjsip_endpoint_identifier_ip.c.

397{
399}
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 227 of file res_pjsip_endpoint_identifier_ip.c.

228{
229 struct ip_identify_match *identify = obj;
230 struct pjsip_rx_data *rdata = arg;
231 pjsip_hdr *header;
232 pj_str_t pj_header_name;
233 int header_present;
234
235 if (ast_strlen_zero(identify->match_header)) {
236 return 0;
237 }
238
239 pj_header_name = pj_str((void *) identify->match_header_name);
240
241 /* Check all headers of the given name for a match. */
242 header_present = 0;
243 for (header = NULL;
244 (header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &pj_header_name, header));
245 header = header->next) {
246 char *pos;
247 int len;
248 char buf[PATH_MAX];
249
250 header_present = 1;
251
252 /* Print header line to buf */
253 len = pjsip_hdr_print_on(header, buf, sizeof(buf) - 1);
254 if (len < 0) {
255 /* Buffer not large enough or no header vptr! */
256 ast_assert(0);
257 continue;
258 }
259 buf[len] = '\0';
260
261 /* Remove header name from pj_buf and trim blanks. */
262 pos = strchr(buf, ':');
263 if (!pos) {
264 /* No header name? Bug in PJPROJECT if so. */
265 ast_assert(0);
266 continue;
267 }
268 pos = ast_strip(pos + 1);
269
270 /* Does header value match what we are looking for? */
271 if (identify->is_header_regex) {
272 if (!regexec(&identify->regex_header_buf, pos, 0, NULL, 0)) {
273 return CMP_MATCH;
274 }
275 } else if (!strcmp(identify->match_header_value, pos)) {
276 return CMP_MATCH;
277 }
278
279 ast_debug(3, "Identify '%s': SIP message has '%s' header but value '%s' does not match '%s'.\n",
281 identify->match_header_name,
282 pos,
283 identify->match_header_value);
284 }
285 if (!header_present) {
286 ast_debug(3, "Identify '%s': SIP message does not have '%s' header.\n",
288 identify->match_header_name);
289 }
290 return 0;
291}
#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 382 of file res_pjsip_endpoint_identifier_ip.c.

383{
384 struct ast_sockaddr addr = { { 0, } };
385
386 ast_sockaddr_parse(&addr, rdata->pkt_info.src_name, PARSE_PORT_FORBID);
387 ast_sockaddr_set_port(&addr, rdata->pkt_info.src_port);
388
390}
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 214 of file res_pjsip_endpoint_identifier_ip.c.

215{
216 struct ip_identify_match *identify = ast_sorcery_generic_alloc(sizeof(*identify), ip_identify_destroy);
217
218 if (!identify || ast_string_field_init(identify, 256)) {
219 ao2_cleanup(identify);
220 return NULL;
221 }
222
223 return identify;
224}
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:1792
#define ast_string_field_init(x, size)
Initialize a field pool and fields.

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

537{
538 struct ip_identify_match *identify = obj;
539 char *current_string;
540 struct ao2_iterator i;
541
542 /* Validate the identify object configuration */
543 if (ast_strlen_zero(identify->endpoint_name)) {
544 ast_log(LOG_ERROR, "Identify '%s' missing required endpoint name.\n",
545 ast_sorcery_object_get_id(identify));
546 return -1;
547 }
548 if (ast_strlen_zero(identify->match_header) /* No header to match */
549 && ast_strlen_zero(identify->match_request_uri) /* and no request to match */
550 /* and no static IP addresses with a mask */
551 && !identify->matches
552 /* and no addresses to resolve */
553 && (!identify->hosts || !ao2_container_count(identify->hosts))) {
554 ast_log(LOG_ERROR, "Identify '%s' is not configured to match anything.\n",
555 ast_sorcery_object_get_id(identify));
556 return -1;
557 }
558
559 if (!ast_strlen_zero(identify->match_header)) {
560 char *c_header;
561 char *c_value;
562 int len;
563
564 /* Split the header name and value */
565 c_header = ast_strdupa(identify->match_header);
566 c_value = strchr(c_header, ':');
567 if (!c_value) {
568 ast_log(LOG_ERROR, "Identify '%s' missing ':' separator in match_header '%s'.\n",
569 ast_sorcery_object_get_id(identify), identify->match_header);
570 return -1;
571 }
572 *c_value = '\0';
573 c_value = ast_strip(c_value + 1);
574 c_header = ast_strip(c_header);
575
576 if (ast_strlen_zero(c_header)) {
577 ast_log(LOG_ERROR, "Identify '%s' has no SIP header to match in match_header '%s'.\n",
578 ast_sorcery_object_get_id(identify), identify->match_header);
579 return -1;
580 }
581
582 if (!strcmp(c_value, "//")) {
583 /* An empty regex is the same as an empty literal string. */
584 c_value = "";
585 }
586
587 if (ast_string_field_set(identify, match_header_name, c_header)
588 || ast_string_field_set(identify, match_header_value, c_value)) {
589 return -1;
590 }
591
592 len = strlen(c_value);
593 if (2 < len && c_value[0] == '/' && c_value[len - 1] == '/') {
594 /* Make "/regex/" into "regex" */
595 c_value[len - 1] = '\0';
596 ++c_value;
597
598 if (regcomp(&identify->regex_header_buf, c_value, REG_EXTENDED | REG_NOSUB)) {
599 ast_log(LOG_ERROR, "Identify '%s' failed to compile match_request_uri regex '%s'.\n",
600 ast_sorcery_object_get_id(identify), c_value);
601 return -1;
602 }
603 identify->is_header_regex = 1;
604 }
605 }
606
607 if (!ast_strlen_zero(identify->match_request_uri)) {
608 char *c_string;
609 int len;
610
611 len = strlen(identify->match_request_uri);
612 c_string = ast_strdupa(identify->match_request_uri);
613
614 if (!strcmp(c_string, "//")) {
615 /* An empty regex is the same as an empty literal string. */
616 c_string = "";
617 }
618
619 if (2 < len && c_string[0] == '/' && c_string[len - 1] == '/') {
620 /* Make "/regex/" into "regex" */
621 c_string[len - 1] = '\0';
622 ++c_string;
623
624 if (regcomp(&identify->regex_request_uri_buf, c_string, REG_EXTENDED | REG_NOSUB)) {
625 ast_log(LOG_ERROR, "Identify '%s' failed to compile match_header regex '%s'.\n",
626 ast_sorcery_object_get_id(identify), c_string);
627 return -1;
628 }
629 identify->is_request_uri_regex = 1;
630 }
631 }
632
633 if (!identify->hosts) {
634 /* No match addresses to resolve */
635 return 0;
636 }
637
638 /* Hosts can produce dynamic content, so mark the identify as such */
640
641 /* Resolve the match addresses now */
642 i = ao2_iterator_init(identify->hosts, 0);
643 while ((current_string = ao2_iterator_next(&i))) {
644 int results = 0;
645 char *colon = strrchr(current_string, ':');
646
647 /* We skip SRV lookup if a colon is present, assuming a port was specified */
648 if (!colon) {
649 /* No port, and we know this is not an IP address, so perform SRV resolution on it */
650 if (identify->srv_lookups) {
651 results = ip_identify_match_srv_lookup(identify, "_sip._udp", current_string,
652 results);
653 if (results != -1) {
654 results = ip_identify_match_srv_lookup(identify, "_sip._tcp",
655 current_string, results);
656 }
657 if (results != -1) {
658 results = ip_identify_match_srv_lookup(identify, "_sips._tcp",
659 current_string, results);
660 }
661 }
662 }
663
664 /* If SRV fails fall back to a normal lookup on the host itself */
665 if (!results) {
666 results = ip_identify_match_host_lookup(identify, current_string);
667 }
668
669 if (results == 0) {
670 ast_log(LOG_WARNING, "Identify '%s' provided address '%s' did not resolve to any address\n",
671 ast_sorcery_object_get_id(identify), current_string);
672 } else if (results == -1) {
673 ast_log(LOG_ERROR, "Identify '%s' failed when adding resolution results of '%s'\n",
674 ast_sorcery_object_get_id(identify), current_string);
675 ao2_ref(current_string, -1);
677 return -1;
678 }
679
680 ao2_ref(current_string, -1);
681 }
683
684 ao2_ref(identify->hosts, -1);
685 identify->hosts = NULL;
686
687 return 0;
688}
#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:2448
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
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 198 of file res_pjsip_endpoint_identifier_ip.c.

199{
200 struct ip_identify_match *identify = obj;
201
203 ast_free_ha(identify->matches);
204 ao2_cleanup(identify->hosts);
205 if (identify->is_header_regex) {
206 regfree(&identify->regex_header_buf);
207 }
208 if (identify->is_request_uri_regex) {
209 regfree(&identify->regex_request_uri_buf);
210 }
211}
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

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

330{
331 struct ip_identify_match *identify = obj;
332 struct ast_sockaddr *addr = arg;
333 int sense;
334
335 sense = ast_apply_ha(identify->matches, addr);
336 if (sense != AST_SENSE_ALLOW) {
337 ast_debug(3, "Source address %s matches identify '%s'\n",
339 ast_sorcery_object_get_id(identify));
340 return CMP_MATCH;
341 } else {
342 ast_debug(3, "Source address %s does not match identify '%s'\n",
344 ast_sorcery_object_get_id(identify));
345 return 0;
346 }
347}
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 480 of file res_pjsip_endpoint_identifier_ip.c.

481{
482 struct ip_identify_match *identify = obj;
483 char *input_string = ast_strdupa(var->value);
484 char *current_string;
485
486 if (ast_strlen_zero(var->value)) {
487 return 0;
488 }
489
490 while ((current_string = ast_strip(strsep(&input_string, ",")))) {
491 char *mask;
492 struct ast_sockaddr address;
493 int error = 0;
494
495 if (ast_strlen_zero(current_string)) {
496 continue;
497 }
498
499 mask = strrchr(current_string, '/');
500
501 /* If it looks like a netmask is present, or we can immediately parse as an IP,
502 * hand things off to the ACL */
503 if (mask || ast_sockaddr_parse(&address, current_string, 0)) {
504 identify->matches = ast_append_ha_with_port("d", current_string, identify->matches, &error);
505
506 if (!identify->matches || error) {
507 ast_log(LOG_ERROR, "Failed to add address '%s' to ip endpoint identifier '%s'\n",
508 current_string, ast_sorcery_object_get_id(obj));
509 return -1;
510 }
511
512 continue;
513 }
514
515 if (!identify->hosts) {
517 if (!identify->hosts) {
518 ast_log(LOG_ERROR, "Failed to create container to store hosts on ip endpoint identifier '%s'\n",
520 return -1;
521 }
522 }
523
524 error = ast_str_container_add(identify->hosts, current_string);
525 if (error) {
526 ast_log(LOG_ERROR, "Failed to store host '%s' for resolution on ip endpoint identifier '%s'\n",
527 current_string, ast_sorcery_object_get_id(obj));
528 return -1;
529 }
530 }
531
532 return 0;
533}
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 * strsep(char **str, const char *delims)
char * address
Definition f2c.h:59
#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,...)

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

416{
417 struct ast_sockaddr *addrs;
418 int num_addrs = 0, error = 0, i;
419 int results = 0;
420
421 num_addrs = ast_sockaddr_resolve(&addrs, host, 0, AST_AF_UNSPEC);
422 if (!num_addrs) {
423 return -1;
424 }
425
426 for (i = 0; i < num_addrs; ++i) {
427 /* Check if the address is already in the list, if so don't add it again */
428 if (identify->matches && (ast_apply_ha(identify->matches, &addrs[i]) != AST_SENSE_ALLOW)) {
429 continue;
430 }
431
432 /* We deny what we actually want to match because there is an implicit permit all rule for ACLs */
433 identify->matches = ast_append_ha_with_port("d", ast_sockaddr_stringify(&addrs[i]), identify->matches, &error);
434
435 if (!identify->matches || error) {
436 results = -1;
437 break;
438 }
439
440 results += 1;
441 }
442
443 ast_free(addrs);
444
445 return results;
446}
@ 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 449 of file res_pjsip_endpoint_identifier_ip.c.

450{
451 char service[NI_MAXHOST];
452 struct srv_context *context = NULL;
453 int srv_ret;
454 const char *srvhost;
455 unsigned short srvport;
456
457 snprintf(service, sizeof(service), "%s.%s", prefix, host);
458
459 while (!(srv_ret = ast_srv_lookup(&context, service, &srvhost, &srvport))) {
460 int hosts;
461
462 /* In the case of the SRV lookup we don't care if it fails, we will output a log message
463 * when we fallback to a normal lookup.
464 */
465 hosts = ip_identify_match_host_lookup(identify, srvhost);
466 if (hosts == -1) {
467 results = -1;
468 break;
469 } else {
470 results += hosts;
471 }
472 }
473
474 ast_srv_cleanup(&context);
475
476 return results;
477}
enum ast_cc_service_type service
Definition ccss.c:389
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(), 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 968 of file res_pjsip_endpoint_identifier_ip.c.

969{
970 ast_sorcery_apply_config(ast_sip_get_sorcery(), "res_pjsip_endpoint_identifier_ip");
971 ast_sorcery_apply_default(ast_sip_get_sorcery(), "identify", "config", "pjsip.conf,criteria=type=identify");
972
975 }
976
977 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "type", "", OPT_NOOP_T, 0, 0);
978 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "endpoint", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, endpoint_name));
980 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "match_header", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, match_header));
981 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));
982 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "srv_lookups", "yes", OPT_BOOL_T, 1, FLDSET(struct ip_identify_match, srv_lookups));
984
989
991 if (!cli_formatter) {
992 ast_log(LOG_ERROR, "Unable to allocate memory for cli formatter\n");
994 }
995 cli_formatter->name = "identify";
1002
1005
1007}
#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:1457
#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.
int(* iterate)(void *container, ao2_callback_fn callback, void *args)
ao2_callback_fn * print_header
void *(* retrieve_by_id)(const char *id)
const char *(* get_id)(const void *obj)
const char * name
ao2_callback_fn * print_body
struct ao2_container *(* get_container)(const char *regex)
#define ARRAY_LEN(a)
Definition utils.h:706

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

691{
693 const struct ip_identify_match *identify = obj;
694
695 ast_ha_join(identify->matches, &str);
697 return 0;
698}
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 *attribute_pure 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 717 of file res_pjsip_endpoint_identifier_ip.c.

718{
719 const struct ip_identify_match *identify = obj;
720 struct ast_variable *head = NULL;
721 struct ast_ha *ha = identify->matches;
722
723 for (; ha; ha = ha->next) {
724 match_to_var_list_append(&head, ha);
725 }
726
727 if (head) {
728 *fields = head;
729 }
730
731 return 0;
732}
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 700 of file res_pjsip_endpoint_identifier_ip.c.

701{
702 char str[MAX_OBJECT_FIELD];
703 const char *addr;
704
705 if (ast_sockaddr_port(&ha->addr)) {
707 } else {
709 }
710
711 snprintf(str, MAX_OBJECT_FIELD, "%s%s/%s", ha->sense == AST_SENSE_ALLOW ? "!" : "",
712 addr, ast_sockaddr_stringify_addr(&ha->netmask));
713
714 ast_variable_list_append(head, ast_variable_new("match", str, ""));
715}
#define ast_variable_new(name, value, filename)
#define ast_variable_list_append(head, new_var)
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 943 of file res_pjsip_endpoint_identifier_ip.c.

945{
946 return ast_sip_cli_traverse_objects(e, cmd, a);
947}
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 1009 of file res_pjsip_endpoint_identifier_ip.c.

1010{
1012
1013 return 0;
1014}
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:1506

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

402{
404}
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 294 of file res_pjsip_endpoint_identifier_ip.c.

295{
296 struct ip_identify_match *identify = obj;
297 struct pjsip_rx_data *rdata = arg;
298 int len;
299 char buf[PJSIP_MAX_URL_SIZE];
300
301 if (ast_strlen_zero(identify->match_request_uri)) {
302 return 0;
303 }
304
305 /* Print request URI to req_buf */
306 len = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, rdata->msg_info.msg->line.req.uri, buf, sizeof(buf) - 1);
307 if (len < 0) {
308 /* Buffer not large enough or no pj uri vptr! */
309 ast_assert(0);
310 } else {
311 /* Terminate the pj_str */
312 buf[len] = '\0';
313 /* Does request URI match what we are looking for? */
314 if (identify->is_request_uri_regex) {
315 if (!regexec(&identify->regex_request_uri_buf, buf, 0, NULL, 0)) {
316 return CMP_MATCH;
317 }
318 } else if (!strcmp(identify->match_request_uri, buf)) {
319 return CMP_MATCH;
320 }
321 ast_debug(3, "Identify '%s': request URI not match '%s' (value='%s').\n",
322 ast_sorcery_object_get_id(identify), identify->match_request_uri, buf);
323 }
324
325 return 0;
326}

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

741{
742 struct ip_identify_match *identify = obj;
743 const char *endpoint_name = arg;
744 struct ast_sip_ami *ami = data;
745 struct ast_str *buf;
746
747 /* Build AMI event */
748 buf = ast_sip_create_ami_event("IdentifyDetail", ami);
749 if (!buf) {
750 return CMP_STOP;
751 }
752 if (sip_identify_to_ami(identify, &buf)) {
753 ast_free(buf);
754 return CMP_STOP;
755 }
756 ast_str_append(&buf, 0, "EndpointName: %s\r\n", endpoint_name);
757
758 /* Send AMI event */
759 astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
760 ++ami->count;
761
762 ast_free(buf);
763 return 0;
764}
@ CMP_STOP
Definition astobj2.h:1028
void astman_append(struct mansession *s, const char *fmt,...)
Definition manager.c:1903
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:3200
struct mansession * s
Definition res_pjsip.h:3202

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

736{
737 return ast_sip_sorcery_object_to_ami(identify, buf);
738}
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 1016 of file res_pjsip_endpoint_identifier_ip.c.

1017{
1024
1025 return 0;
1026}
void ast_cli_unregister_multiple(void)
Definition ael_main.c:408
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 = ASTERISK_GPL_KEY , .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 1035 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 1035 of file res_pjsip_endpoint_identifier_ip.c.

◆ cli_formatter

struct ast_sip_cli_formatter_entry* cli_formatter
static

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

949 {
950AST_CLI_DEFINE(my_cli_traverse_objects, "List PJSIP Identifies",
951 .command = "pjsip list identifies",
952 .usage = "Usage: pjsip list identifies [ like <pattern> ]\n"
953 " List the configured PJSIP Identifies\n"
954 " Optional regular expression pattern is used to filter the list.\n"),
955AST_CLI_DEFINE(my_cli_traverse_objects, "Show PJSIP Identifies",
956 .command = "pjsip show identifies",
957 .usage = "Usage: pjsip show identifies [ like <pattern> ]\n"
958 " Show the configured PJSIP Identifies\n"
959 " Optional regular expression pattern is used to filter the list.\n"),
960AST_CLI_DEFINE(my_cli_traverse_objects, "Show PJSIP Identify",
961 .command = "pjsip show identify",
962 .usage = "Usage: pjsip show identify <id>\n"
963 " Show the configured PJSIP Identify\n"),
964};
#define AST_CLI_DEFINE(fn, txt,...)
Definition cli.h:197
static char * my_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
char * usage
Definition utils/frame.c:37

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

791 {
792 .format_ami = format_ami_endpoint_identify
793};

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

406 {
407 .identify_endpoint = header_identify,
408};

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

392 {
393 .identify_endpoint = ip_identify,
394};

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

410 {
411 .identify_endpoint = request_identify,
412};

Referenced by load_module(), and unload_module().