Asterisk - The Open Source Telephony Project GIT-master-7e7a603
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  ast_sockaddr_with_tp
 Structure for a socket address with transport. More...
 
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 struct ast_sip_endpointtransport_identify (pjsip_rx_data *rdata)
 
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
 
static struct ast_sip_endpoint_identifier transport_identifier
 

Macro Definition Documentation

◆ HOSTS_BUCKETS

#define HOSTS_BUCKETS   53

The number of buckets for storing hosts for resolution.

Definition at line 146 of file res_pjsip_endpoint_identifier_ip.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1090 of file res_pjsip_endpoint_identifier_ip.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1090 of file res_pjsip_endpoint_identifier_ip.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

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

864{
866 struct ao2_container *s_container;
867
869 if (!container) {
870 return NULL;
871 }
872
875 if (!s_container) {
876 return NULL;
877 }
878
879 if (ao2_container_dup(s_container, container, 0)) {
880 ao2_ref(s_container, -1);
881 return NULL;
882 }
883
884 return s_container;
885}
int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags)
Copy all object references in the src container into the dest container.
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
struct ao2_container * container
Definition: res_fax.c:501
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
#define NULL
Definition: resample.c:96
struct ao2_container * ast_sorcery_retrieve_by_regex(const struct ast_sorcery *sorcery, const char *type, const char *regex)
Retrieve multiple objects using a regular expression on their id.
Definition: sorcery.c:1954
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
Definition: sorcery.c:2464
int ast_sorcery_object_id_sort(const void *obj, const void *arg, int flags)
ao2 object sorter based on sorcery id.
Definition: sorcery.c:2440
Generic container type.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

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

Referenced by load_module().

◆ cli_iterator()

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

Definition at line 840 of file res_pjsip_endpoint_identifier_ip.c.

841{
842 const struct ast_sip_endpoint *endpoint = container;
843 struct ao2_container *identifies;
844
845 struct ast_variable fields = {
846 .name = "endpoint",
847 .value = ast_sorcery_object_get_id(endpoint),
848 .next = NULL,
849 };
850
851 identifies = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "identify",
853 if (!identifies) {
854 return -1;
855 }
856
857 ao2_callback(identifies, OBJ_NODATA, callback, args);
858 ao2_cleanup(identifies);
859
860 return 0;
861}
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
@ OBJ_NODATA
Definition: astobj2.h:1044
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2317
@ AST_RETRIEVE_FLAG_MULTIPLE
Return all matching objects.
Definition: sorcery.h:120
void * ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields)
Retrieve an object or multiple objects using specific fields.
Definition: sorcery.c:1897
An entity with which Asterisk communicates.
Definition: res_pjsip.h:963
Structure for variables, used for configurations and for channel variables.
const char * args

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

Referenced by load_module().

◆ cli_print_body()

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

Definition at line 919 of file res_pjsip_endpoint_identifier_ip.c.

920{
922 struct ip_identify_match *ident = obj;
923 struct ast_sip_cli_context *context = arg;
924 struct ast_ha *match;
925 int indent;
926
927 ast_assert(context->output_buffer != NULL);
928
929 ast_str_append(&context->output_buffer, 0, "%*s: %s/%s\n",
930 CLI_INDENT_TO_SPACES(context->indent_level), "Identify",
932
933 if (context->recurse) {
934 context->indent_level++;
935 indent = CLI_INDENT_TO_SPACES(context->indent_level);
936
937 for (match = ident->matches; match; match = match->next) {
938 const char *addr;
939
940 if (ast_sockaddr_port(&match->addr)) {
942 } else {
944 }
945
946 ast_str_append(&context->output_buffer, 0, "%*s: %s%s/%d\n",
947 indent,
948 "Match",
949 match->sense == AST_SENSE_ALLOW ? "!" : "",
950 addr, ast_sockaddr_cidr_bits(&match->netmask));
951 }
952
953 if (!ast_strlen_zero(ident->transport)) {
954 ast_str_append(&context->output_buffer, 0, "%*s: %s\n",
955 indent,
956 "Transport",
957 ident->transport);
958 }
959
960 if (!ast_strlen_zero(ident->match_header)) {
961 ast_str_append(&context->output_buffer, 0, "%*s: %s\n",
962 indent,
963 "Header",
964 ident->match_header);
965 }
966
967 if (!ast_strlen_zero(ident->match_request_uri)) {
968 ast_str_append(&context->output_buffer, 0, "%*s: %s\n",
969 indent,
970 "RequestURI",
971 ident->match_request_uri);
972 }
973
974 context->indent_level--;
975
976 if (context->indent_level == 0) {
977 ast_str_append(&context->output_buffer, 0, "\n");
978 }
979 }
980
981 if (context->show_details
982 || (context->show_details_only_level_0 && context->indent_level == 0)) {
983 ast_str_append(&context->output_buffer, 0, "\n");
985 }
986
987 return 0;
988}
@ AST_SENSE_ALLOW
Definition: acl.h:38
const char * str
Definition: app_jack.c:147
#define ast_free(a)
Definition: astmm.h:180
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2362
int ast_sockaddr_cidr_bits(const struct ast_sockaddr *sa)
Count the 1 bits in a netmask.
Definition: netsock2.c:130
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:517
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:286
int ast_sip_cli_print_sorcery_objectset(void *obj, void *arg, int flags)
Prints a sorcery object's ast_variable list.
Definition: pjsip_cli.c:36
#define CLI_INDENT_TO_SPACES(x)
Definition: res_pjsip_cli.h:29
#define MAX_OBJECT_FIELD
Maximum length of an object field name.
Definition: sorcery.h:110
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
internal representation of ACL entries In principle user applications would have no need for this,...
Definition: acl.h:51
struct ast_sockaddr addr
Definition: acl.h:53
CLI Formatter Context passed to all formatters.
Definition: res_pjsip_cli.h:34
Support for dynamic strings.
Definition: strings.h:623
Structure for an IP identification matching object.
const ast_string_field match_header
struct ast_ha * matches
Networks or addresses that should match this.
const ast_string_field transport
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, str, and ip_identify_match::transport.

Referenced by load_module().

◆ cli_print_header()

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

Definition at line 892 of file res_pjsip_endpoint_identifier_ip.c.

893{
894 struct ast_sip_cli_context *context = arg;
895 int indent = CLI_INDENT_TO_SPACES(context->indent_level);
896 int filler = CLI_MAX_WIDTH - indent - 22;
897
898 ast_assert(context->output_buffer != NULL);
899
900 ast_str_append(&context->output_buffer, 0,
901 "%*s: <Identify/Endpoint%*.*s>\n",
902 indent, "Identify", filler, filler, CLI_HEADER_FILLER);
903
904 if (context->recurse) {
905 context->indent_level++;
906 indent = CLI_INDENT_TO_SPACES(context->indent_level);
907 filler = CLI_LAST_TABSTOP - indent - 24;
908
909 ast_str_append(&context->output_buffer, 0,
910 "%*s: <criteria%*.*s>\n",
911 indent, "Match", filler, filler, CLI_HEADER_FILLER);
912
913 context->indent_level--;
914 }
915
916 return 0;
917}
#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 887 of file res_pjsip_endpoint_identifier_ip.c.

888{
889 return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "identify", id);
890}
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 352 of file res_pjsip_endpoint_identifier_ip.c.

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

813{
814 struct ao2_container *identifies;
815 struct ast_variable fields = {
816 .name = "endpoint",
817 .value = ast_sorcery_object_get_id(endpoint),
818 };
819
820 identifies = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "identify",
822 if (!identifies) {
823 return -1;
824 }
825
826 /* Build and send any found identify object's AMI IdentifyDetail event. */
829 (void *) ast_sorcery_object_get_id(endpoint),
830 ami);
831
832 ao2_ref(identifies, -1);
833 return 0;
834}
#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 435 of file res_pjsip_endpoint_identifier_ip.c.

436{
438}
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 219 of file res_pjsip_endpoint_identifier_ip.c.

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

386{
387 struct ast_sockaddr_with_tp addr_with_tp = { { { 0, } }, };
388 pj_ansi_strxcpy(addr_with_tp.tp, rdata->tp_info.transport->type_name, sizeof(addr_with_tp.tp));
389
390 ast_sockaddr_parse(&addr_with_tp.addr, rdata->pkt_info.src_name, PARSE_PORT_FORBID);
391 ast_sockaddr_set_port(&addr_with_tp.addr, rdata->pkt_info.src_port);
392
393 return common_identify(ip_identify_match_check, &addr_with_tp);
394}
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.
Structure for a socket address with transport.

References ast_sockaddr_with_tp::addr, ast_sockaddr_parse(), ast_sockaddr_set_port, common_identify(), ip_identify_match_check(), PARSE_PORT_FORBID, and ast_sockaddr_with_tp::tp.

◆ ip_identify_alloc()

static void * ip_identify_alloc ( const char *  name)
static

Allocator function for a matching object.

Definition at line 206 of file res_pjsip_endpoint_identifier_ip.c.

207{
208 struct ip_identify_match *identify = ast_sorcery_generic_alloc(sizeof(*identify), ip_identify_destroy);
209
210 if (!identify || ast_string_field_init(identify, 256)) {
211 ao2_cleanup(identify);
212 return NULL;
213 }
214
215 return identify;
216}
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 575 of file res_pjsip_endpoint_identifier_ip.c.

576{
577 struct ip_identify_match *identify = obj;
578 char *current_string;
579 struct ao2_iterator i;
580
581 /* Validate the identify object configuration */
582 if (ast_strlen_zero(identify->endpoint_name)) {
583 ast_log(LOG_ERROR, "Identify '%s' missing required endpoint name.\n",
584 ast_sorcery_object_get_id(identify));
585 return -1;
586 }
587 if (ast_strlen_zero(identify->match_header) /* No header to match */
588 && ast_strlen_zero(identify->match_request_uri) /* and no request to match */
589 /* and no static IP addresses with a mask */
590 && !identify->matches
591 /* and no addresses to resolve */
592 && (!identify->hosts || !ao2_container_count(identify->hosts))) {
593 ast_log(LOG_ERROR, "Identify '%s' is not configured to match anything.\n",
594 ast_sorcery_object_get_id(identify));
595 return -1;
596 }
597
598 if (!ast_strlen_zero(identify->transport)) {
599 if (ast_string_field_set(identify, transport, identify->transport)) {
600 return -1;
601 }
602 }
603
604 if (!ast_strlen_zero(identify->match_header)) {
605 char *c_header;
606 char *c_value;
607 int len;
608
609 /* Split the header name and value */
610 c_header = ast_strdupa(identify->match_header);
611 c_value = strchr(c_header, ':');
612 if (!c_value) {
613 ast_log(LOG_ERROR, "Identify '%s' missing ':' separator in match_header '%s'.\n",
614 ast_sorcery_object_get_id(identify), identify->match_header);
615 return -1;
616 }
617 *c_value = '\0';
618 c_value = ast_strip(c_value + 1);
619 c_header = ast_strip(c_header);
620
621 if (ast_strlen_zero(c_header)) {
622 ast_log(LOG_ERROR, "Identify '%s' has no SIP header to match in match_header '%s'.\n",
623 ast_sorcery_object_get_id(identify), identify->match_header);
624 return -1;
625 }
626
627 if (!strcmp(c_value, "//")) {
628 /* An empty regex is the same as an empty literal string. */
629 c_value = "";
630 }
631
632 if (ast_string_field_set(identify, match_header_name, c_header)
633 || ast_string_field_set(identify, match_header_value, c_value)) {
634 return -1;
635 }
636
637 len = strlen(c_value);
638 if (2 < len && c_value[0] == '/' && c_value[len - 1] == '/') {
639 /* Make "/regex/" into "regex" */
640 c_value[len - 1] = '\0';
641 ++c_value;
642
643 if (regcomp(&identify->regex_header_buf, c_value, REG_EXTENDED | REG_NOSUB)) {
644 ast_log(LOG_ERROR, "Identify '%s' failed to compile match_request_uri regex '%s'.\n",
645 ast_sorcery_object_get_id(identify), c_value);
646 return -1;
647 }
648 identify->is_header_regex = 1;
649 }
650 }
651
652 if (!ast_strlen_zero(identify->match_request_uri)) {
653 char *c_string;
654 int len;
655
656 len = strlen(identify->match_request_uri);
657 c_string = ast_strdupa(identify->match_request_uri);
658
659 if (!strcmp(c_string, "//")) {
660 /* An empty regex is the same as an empty literal string. */
661 c_string = "";
662 }
663
664 if (2 < len && c_string[0] == '/' && c_string[len - 1] == '/') {
665 /* Make "/regex/" into "regex" */
666 c_string[len - 1] = '\0';
667 ++c_string;
668
669 if (regcomp(&identify->regex_request_uri_buf, c_string, REG_EXTENDED | REG_NOSUB)) {
670 ast_log(LOG_ERROR, "Identify '%s' failed to compile match_header regex '%s'.\n",
671 ast_sorcery_object_get_id(identify), c_string);
672 return -1;
673 }
674 identify->is_request_uri_regex = 1;
675 }
676 }
677
678 if (!identify->hosts) {
679 /* No match addresses to resolve */
680 return 0;
681 }
682
683 /* Hosts can produce dynamic content, so mark the identify as such */
685
686 /* Resolve the match addresses now */
687 i = ao2_iterator_init(identify->hosts, 0);
688 while ((current_string = ao2_iterator_next(&i))) {
689 int results = 0;
690 char *colon = strrchr(current_string, ':');
691
692 /* We skip SRV lookup if a colon is present, assuming a port was specified */
693 if (!colon) {
694 /* No port, and we know this is not an IP address, so perform SRV resolution on it */
695 if (identify->srv_lookups) {
696 results = ip_identify_match_srv_lookup(identify, "_sip._udp", current_string,
697 results);
698 if (results != -1) {
699 results = ip_identify_match_srv_lookup(identify, "_sip._tcp",
700 current_string, results);
701 }
702 if (results != -1) {
703 results = ip_identify_match_srv_lookup(identify, "_sips._tcp",
704 current_string, results);
705 }
706 }
707 }
708
709 /* If SRV fails fall back to a normal lookup on the host itself */
710 if (!results) {
711 results = ip_identify_match_host_lookup(identify, current_string);
712 }
713
714 if (results == 0) {
715 ast_log(LOG_WARNING, "Identify '%s' provided address '%s' did not resolve to any address\n",
716 ast_sorcery_object_get_id(identify), current_string);
717 } else if (results == -1) {
718 ast_log(LOG_ERROR, "Identify '%s' failed when adding resolution results of '%s'\n",
719 ast_sorcery_object_get_id(identify), current_string);
720 ao2_ref(current_string, -1);
722 return -1;
723 }
724
725 ao2_ref(current_string, -1);
726 }
728
729 ao2_ref(identify->hosts, -1);
730 identify->hosts = NULL;
731
732 return 0;
733}
#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, ip_identify_match::srv_lookups, and ip_identify_match::transport.

Referenced by load_module().

◆ ip_identify_destroy()

static void ip_identify_destroy ( void *  obj)
static

Destructor function for a matching object.

Definition at line 190 of file res_pjsip_endpoint_identifier_ip.c.

191{
192 struct ip_identify_match *identify = obj;
193
195 ast_free_ha(identify->matches);
196 ao2_cleanup(identify->hosts);
197 if (identify->is_header_regex) {
198 regfree(&identify->regex_header_buf);
199 }
200 if (identify->is_request_uri_regex) {
201 regfree(&identify->regex_request_uri_buf);
202 }
203}
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 321 of file res_pjsip_endpoint_identifier_ip.c.

322{
323 struct ip_identify_match *identify = obj;
324 struct ast_sockaddr_with_tp *addr_with_tp = arg;
325 struct ast_sockaddr address = addr_with_tp->addr;
326 int sense;
327
328 sense = ast_apply_ha(identify->matches, &address);
329 if (sense != AST_SENSE_ALLOW) {
330 ast_debug(3, "Address %s matches identify '%s'\n",
332 ast_sorcery_object_get_id(identify));
333 if (ast_strlen_zero(identify->transport) || !strcasecmp(identify->transport, addr_with_tp->tp)) {
334 ast_debug(3, "Transport %s matches identify '%s'\n",
335 addr_with_tp->tp,
336 ast_sorcery_object_get_id(identify));
337 return CMP_MATCH;
338 } else {
339 ast_debug(3, "Transport %s match not matched identify '%s'\n",
340 addr_with_tp->tp,
341 ast_sorcery_object_get_id(identify));
342 return 0;
343 }
344 } else {
345 ast_debug(3, "Address %s does not match identify '%s'\n",
347 ast_sorcery_object_get_id(identify));
348 return 0;
349 }
350}
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
char * address
Definition: f2c.h:59
Socket address structure.
Definition: netsock2.h:97

References ast_sockaddr_with_tp::addr, ast_apply_ha(), ast_debug, AST_SENSE_ALLOW, ast_sockaddr_stringify(), ast_sorcery_object_get_id(), ast_strlen_zero(), CMP_MATCH, ip_identify_match::matches, ast_sockaddr_with_tp::tp, and ip_identify_match::transport.

Referenced by ip_identify(), and transport_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 519 of file res_pjsip_endpoint_identifier_ip.c.

520{
521 struct ip_identify_match *identify = obj;
522 char *input_string = ast_strdupa(var->value);
523 char *current_string;
524
525 if (ast_strlen_zero(var->value)) {
526 return 0;
527 }
528
529 while ((current_string = ast_strip(strsep(&input_string, ",")))) {
530 char *mask;
531 struct ast_sockaddr address;
532 int error = 0;
533
534 if (ast_strlen_zero(current_string)) {
535 continue;
536 }
537
538 mask = strrchr(current_string, '/');
539
540 /* If it looks like a netmask is present, or we can immediately parse as an IP,
541 * hand things off to the ACL */
542 if (mask || ast_sockaddr_parse(&address, current_string, 0)) {
543 identify->matches = ast_append_ha_with_port("d", current_string, identify->matches, &error);
544
545 if (!identify->matches || error) {
546 ast_log(LOG_ERROR, "Failed to add address '%s' to ip endpoint identifier '%s'\n",
547 current_string, ast_sorcery_object_get_id(obj));
548 return -1;
549 }
550
551 continue;
552 }
553
554 if (!identify->hosts) {
556 if (!identify->hosts) {
557 ast_log(LOG_ERROR, "Failed to create container to store hosts on ip endpoint identifier '%s'\n",
559 return -1;
560 }
561 }
562
563 error = ast_str_container_add(identify->hosts, current_string);
564 if (error) {
565 ast_log(LOG_ERROR, "Failed to store host '%s' for resolution on ip endpoint identifier '%s'\n",
566 current_string, ast_sorcery_object_get_id(obj));
567 return -1;
568 }
569 }
570
571 return 0;
572}
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)
#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 454 of file res_pjsip_endpoint_identifier_ip.c.

455{
456 struct ast_sockaddr *addrs;
457 int num_addrs = 0, error = 0, i;
458 int results = 0;
459
460 num_addrs = ast_sockaddr_resolve(&addrs, host, 0, AST_AF_UNSPEC);
461 if (!num_addrs) {
462 return -1;
463 }
464
465 for (i = 0; i < num_addrs; ++i) {
466 /* Check if the address is already in the list, if so don't add it again */
467 if (identify->matches && (ast_apply_ha(identify->matches, &addrs[i]) != AST_SENSE_ALLOW)) {
468 continue;
469 }
470
471 /* We deny what we actually want to match because there is an implicit permit all rule for ACLs */
472 identify->matches = ast_append_ha_with_port("d", ast_sockaddr_stringify(&addrs[i]), identify->matches, &error);
473
474 if (!identify->matches || error) {
475 results = -1;
476 break;
477 }
478
479 results += 1;
480 }
481
482 ast_free(addrs);
483
484 return results;
485}
@ 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 488 of file res_pjsip_endpoint_identifier_ip.c.

489{
490 char service[NI_MAXHOST];
491 struct srv_context *context = NULL;
492 int srv_ret;
493 const char *srvhost;
494 unsigned short srvport;
495
496 snprintf(service, sizeof(service), "%s.%s", prefix, host);
497
498 while (!(srv_ret = ast_srv_lookup(&context, service, &srvhost, &srvport))) {
499 int hosts;
500
501 /* In the case of the SRV lookup we don't care if it fails, we will output a log message
502 * when we fallback to a normal lookup.
503 */
504 hosts = ip_identify_match_host_lookup(identify, srvhost);
505 if (hosts == -1) {
506 results = -1;
507 break;
508 } else {
509 results += hosts;
510 }
511 }
512
514
515 return results;
516}
enum ast_cc_service_type service
Definition: ccss.c:383
static char prefix[MAX_PREFIX]
Definition: http.c:144
void ast_srv_cleanup(struct srv_context **context)
Cleanup resources associated with ast_srv_lookup.
Definition: srv.c:248
int ast_srv_lookup(struct srv_context **context, const char *service, const char **host, unsigned short *port)
Retrieve set of SRV lookups, in order.
Definition: srv.c:202

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

Referenced by ip_identify_apply().

◆ load_module()

static int load_module ( void  )
static

Definition at line 1020 of file res_pjsip_endpoint_identifier_ip.c.

1021{
1022 ast_sorcery_apply_config(ast_sip_get_sorcery(), "res_pjsip_endpoint_identifier_ip");
1023 ast_sorcery_apply_default(ast_sip_get_sorcery(), "identify", "config", "pjsip.conf,criteria=type=identify");
1024
1027 }
1028
1029 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "type", "", OPT_NOOP_T, 0, 0);
1030 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "endpoint", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, endpoint_name));
1032 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "match_header", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, match_header));
1033 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));
1034 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "srv_lookups", "yes", OPT_BOOL_T, 1, FLDSET(struct ip_identify_match, srv_lookups));
1035 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "transport", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, transport));
1037
1043
1045 if (!cli_formatter) {
1046 ast_log(LOG_ERROR, "Unable to allocate memory for cli formatter\n");
1048 }
1049 cli_formatter->name = "identify";
1056
1059
1061}
#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_endpoint_identifier transport_identifier
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, STRFLDSET, and transport_identifier.

◆ match_to_str()

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

Definition at line 735 of file res_pjsip_endpoint_identifier_ip.c.

736{
738 const struct ip_identify_match *identify = obj;
739
740 ast_ha_join(identify->matches, &str);
742 return 0;
743}
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 762 of file res_pjsip_endpoint_identifier_ip.c.

763{
764 const struct ip_identify_match *identify = obj;
765 struct ast_variable *head = NULL;
766 struct ast_ha *ha = identify->matches;
767
768 for (; ha; ha = ha->next) {
769 match_to_var_list_append(&head, ha);
770 }
771
772 if (head) {
773 *fields = head;
774 }
775
776 return 0;
777}
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 745 of file res_pjsip_endpoint_identifier_ip.c.

746{
747 char str[MAX_OBJECT_FIELD];
748 const char *addr;
749
750 if (ast_sockaddr_port(&ha->addr)) {
752 } else {
754 }
755
756 snprintf(str, MAX_OBJECT_FIELD, "%s%s/%s", ha->sense == AST_SENSE_ALLOW ? "!" : "",
758
759 ast_variable_list_append(head, ast_variable_new("match", str, ""));
760}
#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 995 of file res_pjsip_endpoint_identifier_ip.c.

997{
998 return ast_sip_cli_traverse_objects(e, cmd, a);
999}
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 1063 of file res_pjsip_endpoint_identifier_ip.c.

1064{
1066
1067 return 0;
1068}
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 440 of file res_pjsip_endpoint_identifier_ip.c.

441{
443}
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 286 of file res_pjsip_endpoint_identifier_ip.c.

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

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

786{
787 struct ip_identify_match *identify = obj;
788 const char *endpoint_name = arg;
789 struct ast_sip_ami *ami = data;
790 struct ast_str *buf;
791
792 /* Build AMI event */
793 buf = ast_sip_create_ami_event("IdentifyDetail", ami);
794 if (!buf) {
795 return CMP_STOP;
796 }
797 if (sip_identify_to_ami(identify, &buf)) {
798 ast_free(buf);
799 return CMP_STOP;
800 }
801 ast_str_append(&buf, 0, "EndpointName: %s\r\n", endpoint_name);
802
803 /* Send AMI event */
804 astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
805 ++ami->count;
806
807 ast_free(buf);
808 return 0;
809}
@ CMP_STOP
Definition: astobj2.h:1028
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3302
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:3047
struct mansession * s
Definition: res_pjsip.h:3049

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

781{
782 return ast_sip_sorcery_object_to_ami(identify, buf);
783}
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().

◆ transport_identify()

static struct ast_sip_endpoint * transport_identify ( pjsip_rx_data *  rdata)
static

Definition at line 396 of file res_pjsip_endpoint_identifier_ip.c.

397{
398 char buffer[PJ_INET6_ADDRSTRLEN];
399 pj_status_t status;
400 struct ast_sockaddr_with_tp addr_with_tp = { { { 0, } }, };
401 union pj_sockaddr sock = rdata->tp_info.transport->local_addr;
402
403 pj_ansi_strxcpy(addr_with_tp.tp, rdata->tp_info.transport->type_name, sizeof(addr_with_tp.tp));
404
405 if (sock.addr.sa_family == PJ_AF_INET6) {
406 status = pj_inet_ntop(PJ_AF_INET6, &(sock.ipv6.sin6_addr), buffer, PJ_INET6_ADDRSTRLEN);
407 if (status == PJ_SUCCESS && !strcmp(buffer, "::")) {
408 ast_log(LOG_WARNING, "Matching against '::' may be unpredictable.\n");
409 }
410 } else {
411 status = pj_inet_ntop(PJ_AF_INET, &(sock.ipv4.sin_addr), buffer, PJ_INET_ADDRSTRLEN);
412 if (status == PJ_SUCCESS && !strcmp(buffer, "0.0.0.0")) {
413 ast_log(LOG_WARNING, "Matching against '0.0.0.0' may be unpredictable.\n");
414 }
415 }
416
417 if (status == PJ_SUCCESS) {
418 ast_sockaddr_parse(&addr_with_tp.addr, buffer, PARSE_PORT_FORBID);
419 ast_sockaddr_set_port(&addr_with_tp.addr, rdata->tp_info.transport->local_name.port);
420
421 return common_identify(ip_identify_match_check, &addr_with_tp);
422 } else {
423 return NULL;
424 }
425}
jack_status_t status
Definition: app_jack.c:146

References ast_sockaddr_with_tp::addr, ast_log, ast_sockaddr_parse(), ast_sockaddr_set_port, common_identify(), ip_identify_match_check(), LOG_WARNING, NULL, PARSE_PORT_FORBID, status, and ast_sockaddr_with_tp::tp.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1070 of file res_pjsip_endpoint_identifier_ip.c.

1071{
1079
1080 return 0;
1081}
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, request_identifier, and transport_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 1090 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 1090 of file res_pjsip_endpoint_identifier_ip.c.

◆ cli_formatter

struct ast_sip_cli_formatter_entry* cli_formatter
static

Definition at line 1018 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 1001 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 836 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 445 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 427 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 449 of file res_pjsip_endpoint_identifier_ip.c.

Referenced by load_module(), and unload_module().

◆ transport_identifier

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

Definition at line 431 of file res_pjsip_endpoint_identifier_ip.c.

Referenced by load_module(), and unload_module().