28#include <netinet/in.h>
64} __attribute__((__packed__));
176 for (i = 0; i < size; ++i) {
178 if (pjsip_method_cmp(&candidate->
method,
method) == 0) {
196 if (
session->log_all_traffic) {
223 pj_sockaddr *source, pj_sockaddr *destination)
228 .ts_usec = now.tv_usec,
240 void *pcap_ip_header;
241 size_t pcap_ip_header_len;
258 if ((source && source->addr.sa_family == pj_AF_INET()) ||
259 (destination && destination->addr.sa_family == pj_AF_INET())) {
267 memcpy(&
pcap_ipv4_header.
ip_dst, pj_sockaddr_get_addr(destination), pj_sockaddr_get_addr_len(destination));
297 if (fwrite(pcap_ip_header, pcap_ip_header_len, 1,
session->pcap_file) != 1) {
303 if (fwrite(msg, msg_len, 1,
session->pcap_file) != 1) {
322 ast_verbose(
"<--- Transmitting SIP %s (%d bytes) to %s:%s --->\n%.*s\n",
323 tdata->msg->type == PJSIP_REQUEST_MSG ?
"request" :
"response",
324 (
int) (tdata->buf.cur - tdata->buf.start),
325 tdata->tp_info.transport->type_name,
326 pj_sockaddr_print(&tdata->tp_info.dst_addr, buffer,
sizeof(buffer), 3),
327 (
int) (tdata->buf.end - tdata->buf.start), tdata->buf.start);
332 NULL, &tdata->tp_info.dst_addr);
342 if (!rdata->msg_info.msg) {
354 ast_verbose(
"<--- Received SIP %s (%d bytes) from %s:%s --->\n%s\n",
355 rdata->msg_info.msg->type == PJSIP_REQUEST_MSG ?
"request" :
"response",
357 rdata->tp_info.transport->type_name,
358 pj_sockaddr_print(&rdata->pkt_info.src_addr, buffer,
sizeof(buffer), 3),
359 rdata->pkt_info.packet);
364 &rdata->pkt_info.src_addr,
NULL);
371 .name = {
"Logging Module", 14 },
387 ast_cli(fd,
"PJSIP Logging enabled\n");
395 const char *host = arg;
411 mask = strrchr(host,
'/');
423 ast_cli(fd,
"Failed to add address '%s' for logging\n", host);
440 size_t method_bytes = strlen(
method);
449 pj_strset(&
info->pj_name,
info->name, method_bytes);
450 pjsip_method_init_np(&
info->method, &
info->pj_name);
458 return pjsip_method_cmp(&element->
method, &candidate->
method) == 0
467 return strcasecmp((*m_a)->name, (*m_b)->name);
491 ast_cli(fd,
"Method '%s' is already enabled\n",
method->name);
550 ast_cli(fd,
"PJSIP Logging disabled\n");
562 ast_cli(fd,
"PJSIP Logging to verbose has been %s\n",
ast_true(arg) ?
"enabled" :
"disabled");
588 ast_cli(fd,
"Failed to open file '%s' for pcap writing\n", arg);
596 ast_cli(fd,
"PJSIP logging to pcap file '%s'\n", arg);
616 static const char *
const method_choices[] = {
617 "INVITE",
"CANCEL",
"ACK",
618 "BYE",
"REGISTER",
"OPTIONS",
619 "SUBSCRIBE",
"NOTIFY",
"PUBLISH",
627 e->
command =
"pjsip set logger {on|off|host|add|method|methodadd|verbose|pcap}";
629 "Usage: pjsip set logger {on|off|host <name/subnet>|add <name/subnet>|method <method>|methodadd <method>|verbose <on/off>|pcap <filename>}\n"
630 " Enables or disabling logging of SIP packets\n"
631 " read on ports bound to PJSIP transports either\n"
632 " globally or enables logging for an individual\n"
633 " host or particular SIP method(s).\n"
634 " Messages can be filtered by SIP request methods\n"
635 " INVITE, CANCEL, ACK, BYE, REGISTER, OPTIONS,\n"
636 " SUBSCRIBE, NOTIFY, PUBLISH, INFO, and MESSAGE\n";
639 if (
a->argc && !strncasecmp(
a->argv[e->
args - 1],
"method", 6)) {
645 what =
a->argv[e->
args - 1];
647 if (
a->argc == e->
args) {
648 if (!strcasecmp(what,
"on")) {
651 }
else if (!strcasecmp(what,
"off")) {
655 }
else if (
a->argc == e->
args + 1) {
656 if (!strcasecmp(what,
"host")) {
659 }
else if (!strcasecmp(what,
"add")) {
662 }
else if (!strcasecmp(what,
"method")) {
665 }
else if (!strcasecmp(what,
"methodadd")) {
668 }
else if (!strcasecmp(what,
"verbose")) {
671 }
else if (!strcasecmp(what,
"pcap")) {
697 ast_debug(3,
"Leaving logger enabled since logging settings overridden using CLI\n");
708 ast_debug(3,
"Leaving logger alone since logging has been overridden using CLI\n");
780 .
requires =
"res_pjsip",
Access Control of various sorts.
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
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.
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.
Asterisk main include file. File version handling, generic pbx functions.
static struct ast_mansession session
#define ast_calloc(num, len)
A wrapper for calloc()
@ AO2_ALLOC_OPT_LOCK_RWLOCK
#define ao2_alloc_options(data_size, destructor_fn, options)
Standard Command Line Interface.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define AST_CLI_DEFINE(fn, txt,...)
void ast_cli(int fd, const char *fmt,...)
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
void ast_verbose(const char *fmt,...)
Support for logging to various files, console and syslog Configuration in file logger....
#define ast_debug(level,...)
Log a DEBUG message.
Asterisk module definitions.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODULE_SUPPORT_CORE
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
int ast_sockaddr_resolve_first_af(struct ast_sockaddr *addr, const char *name, int flag, int family)
Return the first entry from ast_sockaddr_resolve filtered by address family.
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
#define AST_SOCKADDR_BUFLEN
void ast_sip_unregister_service(pjsip_module *module)
int ast_sip_register_service(pjsip_module *module)
Register a SIP service in Asterisk.
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
char * ast_sip_get_debug(void)
Retrieve the system debug setting (yes|no|host).
static enum pjsip_logger_mask logger_config_settings
static void pjsip_logger_write_to_pcap(struct pjsip_logger_session *session, const char *msg, size_t msg_len, pj_sockaddr *source, pj_sockaddr *destination)
static char * pjsip_enable_logger_method(int fd, const char *arg, int add_method)
Add the current or an additional method to match for filtering.
static int apply_method_filter(const struct pjsip_logger_session *session, const pjsip_method *method)
static struct method_logging_info * method_logging_info_alloc(const char *method)
static enum pjsip_logger_mask logger_cli_settings
static struct ast_cli_entry cli_pjsip[]
static char * pjsip_enable_logger_all(int fd)
static char * pjsip_set_logger(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct pjsip_logger_session * default_logger
The default logger session.
static pjsip_module logging_module
static char * pjsip_set_logger_verbose(int fd, const char *arg)
@ AST_PJSIP_LOGGER_VERBOSE
@ AST_PJSIP_LOGGER_METHOD
static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata)
static int method_logging_info_cmp(const struct method_logging_info *element, const struct method_logging_info *candidate)
static char * pjsip_set_logger_pcap(int fd, const char *arg)
static void check_debug(void)
static int method_logging_info_sort_cmp(const void *a, const void *b)
static struct pjsip_logger_session * pjsip_logger_session_alloc(void)
Allocator for logger session.
static int load_module(void)
static void global_reloaded(const char *object_type)
static int pjsip_log_test_filter(const struct pjsip_logger_session *session, const char *address, int port, const pjsip_method *method)
See if we pass debug filter.
static int unload_module(void)
static const struct ast_sorcery_observer global_observer
static void pjsip_logger_session_destroy(void *obj)
Destructor for logger session.
static char * pjsip_enable_logger_host(int fd, const char *arg, unsigned int add_host)
static char * pjsip_disable_logger(int fd)
static pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata)
static int debug
Global debug status.
void ast_sorcery_observer_remove(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Remove an observer from a specific object type.
int ast_sorcery_observer_add(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Add an observer to a specific object type.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
static force_inline int attribute_pure ast_strlen_zero(const char *s)
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"....
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
descriptor for a cli entry.
int args
This gets set in ast_cli_register()
internal representation of ACL entries In principle user applications would have no need for this,...
Socket address structure.
Interface for a sorcery object type observer.
void(* loaded)(const char *object_type)
Callback for when an object type is loaded/reloaded.
Support for dynamic strings.
char name[]
The PJSIP method structure used for comparisons.
pjsip_method method
A PJSIP string for the method.
struct ast_ha * matches
Explicit addresses or ranges being logged.
unsigned int log_to_verbose
Whether to log to verbose or not.
struct pjsip_logger_session::@459 log_methods
Vector of SIP methods to log.
unsigned int enabled
Whether the session is enabled or not.
unsigned int log_all_traffic
Whether the session is logging all traffic or not.
char pcap_filename[PATH_MAX]
Filename used for the pcap file.
FILE * pcap_file
The pcap file itself.
unsigned int log_to_pcap
Whether to log to pcap or not.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
int error(const char *format,...)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Vector container support.
#define AST_VECTOR_RESET(vec, cleanup)
Reset vector.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
#define AST_VECTOR_SORT(vec, cmp)
Sort a vector in-place.
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
#define AST_VECTOR_CALLBACK(vec, callback, default_value,...)
Execute a callback on every element in a vector returning the first matched.
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
#define AST_VECTOR(name, type)
Define a vector structure.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.