Asterisk - The Open Source Telephony Project GIT-master-8f1982c
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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 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:531
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 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)
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:1051
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(), 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 ? "!" : "",
905 addr, ast_sockaddr_cidr_bits(&match->netmask));
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");
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)
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 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
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 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: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 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: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 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: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 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
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 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,...)
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 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}
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
@ AST_AF_UNSPEC
Definition: netsock2.h:54

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
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(), 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 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: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 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 * 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 ? "!" : "",
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)
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 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: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 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:1907
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}
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 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.

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.

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.

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.

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.

Referenced by load_module(), and unload_module().