<p>Friendly Automation <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/14441">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  George Joseph: Looks good to me, approved
  Friendly Automation: Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_pjsip_logger: Expand functionality to improve logging.<br><br>The PJSIP packet logger now has the following CLI commands:<br><br>pjsip set logger pcap <filename><br><br>When used this will create a pcap file containing the incoming<br>and outgoing SIP packets, in unencrypted form.<br><br>pjsip set logger verbose <on / off><br><br>This allows you to toggle logging to verbose on and off.<br><br>pjsip set logger host <IP/subnet mask> add<br><br>This allows you to add an additional IP address or subnet<br>mask to logging, allowing you to log multiple instead of<br>just a single IP address or all traffic.<br><br>The normal "pjsip set logger host" CLI command has also been<br>expanded to allow subnet masks as well.<br><br>ASTERISK-28895<br><br>Change-Id: If5859161a72b0d7dd2d1f92d45bed88e0cd07d0e<br>---<br>A doc/CHANGES-staging/pjsip_logger_improvements.txt<br>M res/res_pjsip_logger.c<br>2 files changed, 421 insertions(+), 55 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/doc/CHANGES-staging/pjsip_logger_improvements.txt b/doc/CHANGES-staging/pjsip_logger_improvements.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..1a16be9</span><br><span>--- /dev/null</span><br><span>+++ b/doc/CHANGES-staging/pjsip_logger_improvements.txt</span><br><span>@@ -0,0 +1,21 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: res_pjsip_logger</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+The PJSIP packet logger now has the following CLI commands:</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+pjsip set logger pcap <filename></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+When used this will create a pcap file containing the incoming</span><br><span style="color: hsl(120, 100%, 40%);">+and outgoing SIP packets, in unencrypted form.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+pjsip set logger console <on / off></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+This allows you to toggle logging to console on and off.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+pjsip set logger host <IP/subnet mask> add</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+This allows you to add an additional IP address or subnet</span><br><span style="color: hsl(120, 100%, 40%);">+mask to logging, allowing you to log multiple instead of</span><br><span style="color: hsl(120, 100%, 40%);">+just a single IP address or all traffic.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+The normal "pjsip set logger host" CLI command has also been</span><br><span style="color: hsl(120, 100%, 40%);">+expanded to allow subnet masks as well.</span><br><span>diff --git a/res/res_pjsip_logger.c b/res/res_pjsip_logger.c</span><br><span>index 172deec..cc79f61 100644</span><br><span>--- a/res/res_pjsip_logger.c</span><br><span>+++ b/res/res_pjsip_logger.c</span><br><span>@@ -25,6 +25,8 @@</span><br><span> </span><br><span> #include "asterisk.h"</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <netinet/in.h>  /* For IPPROTO_UDP and in6_addr */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #include <pjsip.h></span><br><span> </span><br><span> #include "asterisk/res_pjsip.h"</span><br><span>@@ -32,60 +34,262 @@</span><br><span> #include "asterisk/logger.h"</span><br><span> #include "asterisk/cli.h"</span><br><span> #include "asterisk/netsock2.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/acl.h"</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-enum pjsip_logging_mode {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGGING_MODE_DISABLED,    /* No logging is enabled */</span><br><span style="color: hsl(0, 100%, 40%);">-   LOGGING_MODE_ENABLED,     /* Logging is enabled */</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief PCAP Header */</span><br><span style="color: hsl(120, 100%, 40%);">+struct pcap_header {</span><br><span style="color: hsl(120, 100%, 40%);">+   uint32_t magic_number;  /*! \brief PCAP file format magic number */</span><br><span style="color: hsl(120, 100%, 40%);">+   uint16_t version_major; /*! \brief Major version number of the file format */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t version_minor; /*! \brief Minor version number of the file format */</span><br><span style="color: hsl(120, 100%, 40%);">+ int32_t thiszone;       /*! \brief GMT to local correction */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t sigfigs;       /*! \brief Accuracy of timestamps */</span><br><span style="color: hsl(120, 100%, 40%);">+  uint32_t snaplen;       /*! \brief The maximum size that can be recorded in the file */</span><br><span style="color: hsl(120, 100%, 40%);">+       uint32_t network;       /*! \brief Type of packets held within the file */</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static enum pjsip_logging_mode logging_mode;</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_sockaddr log_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief PCAP Packet Record Header */</span><br><span style="color: hsl(120, 100%, 40%);">+struct pcap_record_header {</span><br><span style="color: hsl(120, 100%, 40%);">+    uint32_t ts_sec;        /*! \brief When the record was created */</span><br><span style="color: hsl(120, 100%, 40%);">+     uint32_t ts_usec;       /*! \brief When the record was created */</span><br><span style="color: hsl(120, 100%, 40%);">+     uint32_t incl_len;      /*! \brief Length of packet as saved in the file */</span><br><span style="color: hsl(120, 100%, 40%);">+   uint32_t orig_len;      /*! \brief Length of packet as sent over network */</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief PCAP Ethernet Header */</span><br><span style="color: hsl(120, 100%, 40%);">+struct pcap_ethernet_header {</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t dst[6]; /*! \brief Destination MAC address */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t src[6]; /*! \brief Source MAD address */</span><br><span style="color: hsl(120, 100%, 40%);">+      uint16_t type;  /*! \brief The type of packet contained within */</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__((__packed__));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief PCAP IPv4 Header */</span><br><span style="color: hsl(120, 100%, 40%);">+struct pcap_ipv4_header {</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t ver_ihl;        /*! \brief IP header version and other bits */</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t ip_tos;         /*! \brief Type of service details */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t ip_len;        /*! \brief Total length of the packet (including IPv4 header) */</span><br><span style="color: hsl(120, 100%, 40%);">+      uint16_t ip_id;         /*! \brief Identification value */</span><br><span style="color: hsl(120, 100%, 40%);">+    uint16_t ip_off;        /*! \brief Fragment offset */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t ip_ttl;         /*! \brief Time to live for the packet */</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t ip_protocol;    /*! \brief Protocol of the data held within the packet (always UDP) */</span><br><span style="color: hsl(120, 100%, 40%);">+        uint16_t ip_sum;        /*! \brief Checksum (not calculated for our purposes */</span><br><span style="color: hsl(120, 100%, 40%);">+       uint32_t ip_src;        /*! \brief Source IP address */</span><br><span style="color: hsl(120, 100%, 40%);">+       uint32_t ip_dst;        /*! \brief Destination IP address */</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief PCAP IPv6 Header */</span><br><span style="color: hsl(120, 100%, 40%);">+struct pcap_ipv6_header {</span><br><span style="color: hsl(120, 100%, 40%);">+   union {</span><br><span style="color: hsl(120, 100%, 40%);">+      struct ip6_hdrctl {</span><br><span style="color: hsl(120, 100%, 40%);">+         uint32_t ip6_un1_flow; /*! \brief Version, traffic class, flow label */</span><br><span style="color: hsl(120, 100%, 40%);">+         uint16_t ip6_un1_plen; /*! \brief Length of the packet (not including IPv6 header) */</span><br><span style="color: hsl(120, 100%, 40%);">+         uint8_t ip6_un1_nxt;   /*! \brief Next header field */</span><br><span style="color: hsl(120, 100%, 40%);">+         uint8_t ip6_un1_hlim; /*! \brief Hop Limit */</span><br><span style="color: hsl(120, 100%, 40%);">+      } ip6_un1;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t ip6_un2_vfc;   /*! \brief Version, traffic class */</span><br><span style="color: hsl(120, 100%, 40%);">+   } ip6_ctlun;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct in6_addr ip6_src; /*! \brief Source IP address */</span><br><span style="color: hsl(120, 100%, 40%);">+   struct in6_addr ip6_dst; /*! \brief Destination IP address */</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief PCAP UDP Header */</span><br><span style="color: hsl(120, 100%, 40%);">+struct pcap_udp_header {</span><br><span style="color: hsl(120, 100%, 40%);">+   uint16_t src;           /*! \brief Source IP port */</span><br><span style="color: hsl(120, 100%, 40%);">+  uint16_t dst;           /*! \brief Destination IP port */</span><br><span style="color: hsl(120, 100%, 40%);">+     uint16_t length;        /*! \brief Length of the UDP header plus UDP packet */</span><br><span style="color: hsl(120, 100%, 40%);">+        uint16_t checksum;      /*! \brief Packet checksum, left uncalculated for our purposes */</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief PJSIP Logging Session */</span><br><span style="color: hsl(120, 100%, 40%);">+struct pjsip_logger_session {</span><br><span style="color: hsl(120, 100%, 40%);">+   /*! \brief Explicit addresses or ranges being logged */</span><br><span style="color: hsl(120, 100%, 40%);">+       struct ast_ha *matches;</span><br><span style="color: hsl(120, 100%, 40%);">+       /*! \brief Filename used for the pcap file */</span><br><span style="color: hsl(120, 100%, 40%);">+ char pcap_filename[PATH_MAX];</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! \brief The pcap file itself */</span><br><span style="color: hsl(120, 100%, 40%);">+    FILE *pcap_file;</span><br><span style="color: hsl(120, 100%, 40%);">+      /*! \brief Whether the session is enabled or not */</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned int enabled:1;</span><br><span style="color: hsl(120, 100%, 40%);">+       /*! \brief Whether the session is logging all traffic or not */</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned int log_all_traffic:1;</span><br><span style="color: hsl(120, 100%, 40%);">+       /*! \brief Whether to log to verbose or not */</span><br><span style="color: hsl(120, 100%, 40%);">+        unsigned int log_to_verbose:1;</span><br><span style="color: hsl(120, 100%, 40%);">+        /*! \brief Whether to log to pcap or not */</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned int log_to_pcap:1;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief The default logger session */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct pjsip_logger_session *default_logger;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief Destructor for logger session */</span><br><span style="color: hsl(120, 100%, 40%);">+static void pjsip_logger_session_destroy(void *obj)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct pjsip_logger_session *session = obj;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (session->pcap_file) {</span><br><span style="color: hsl(120, 100%, 40%);">+          fclose(session->pcap_file);</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_free_ha(session->matches);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief Allocator for logger session */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct pjsip_logger_session *pjsip_logger_session_alloc(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct pjsip_logger_session *session;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       session = ao2_alloc_options(sizeof(struct pjsip_logger_session), pjsip_logger_session_destroy,</span><br><span style="color: hsl(120, 100%, 40%);">+                AO2_ALLOC_OPT_LOCK_RWLOCK);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!session) {</span><br><span style="color: hsl(120, 100%, 40%);">+               return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   session->log_to_verbose = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     return session;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> </span><br><span> /*! \brief See if we pass debug IP filter */</span><br><span style="color: hsl(0, 100%, 40%);">-static inline int pjsip_log_test_addr(const char *address, int port)</span><br><span style="color: hsl(120, 100%, 40%);">+static inline int pjsip_log_test_addr(const struct pjsip_logger_session *session, const char *address, int port)</span><br><span> {</span><br><span>    struct ast_sockaddr test_addr;</span><br><span style="color: hsl(0, 100%, 40%);">-  if (logging_mode == LOGGING_MODE_DISABLED) {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!session->enabled) {</span><br><span>          return 0;</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* A null logging address means we'll debug any address */</span><br><span style="color: hsl(0, 100%, 40%);">-  if (ast_sockaddr_isnull(&log_addr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+     if (session->log_all_traffic) {</span><br><span>           return 1;</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* A null address was passed in. Just reject it. */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (ast_strlen_zero(address)) {</span><br><span style="color: hsl(120, 100%, 40%);">+       /* A null address was passed in or no explicit matches. Just reject it. */</span><br><span style="color: hsl(120, 100%, 40%);">+    if (ast_strlen_zero(address) || !session->matches) {</span><br><span>              return 0;</span><br><span>    }</span><br><span> </span><br><span>        ast_sockaddr_parse(&test_addr, address, PARSE_PORT_IGNORE);</span><br><span>      ast_sockaddr_set_port(&test_addr, port);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        /* If no port was specified for a debug address, just compare the</span><br><span style="color: hsl(0, 100%, 40%);">-        * addresses, otherwise compare the address and port</span><br><span style="color: hsl(0, 100%, 40%);">-     */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (ast_sockaddr_port(&log_addr)) {</span><br><span style="color: hsl(0, 100%, 40%);">-         return !ast_sockaddr_cmp(&log_addr, &test_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Compare the address against the matches */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_apply_ha(session->matches, &test_addr) != AST_SENSE_ALLOW) {</span><br><span style="color: hsl(120, 100%, 40%);">+           return 1;</span><br><span>    } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                return !ast_sockaddr_cmp_addr(&log_addr, &test_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+         return 0;</span><br><span>    }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void pjsip_logger_write_to_pcap(struct pjsip_logger_session *session, const char *msg, size_t msg_len,</span><br><span style="color: hsl(120, 100%, 40%);">+     pj_sockaddr *source, pj_sockaddr *destination)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct timeval now = ast_tvnow();</span><br><span style="color: hsl(120, 100%, 40%);">+     struct pcap_record_header pcap_record_header = {</span><br><span style="color: hsl(120, 100%, 40%);">+              .ts_sec = now.tv_sec,</span><br><span style="color: hsl(120, 100%, 40%);">+         .ts_usec = now.tv_usec,</span><br><span style="color: hsl(120, 100%, 40%);">+       };</span><br><span style="color: hsl(120, 100%, 40%);">+    struct pcap_ethernet_header pcap_ethernet_header = {</span><br><span style="color: hsl(120, 100%, 40%);">+          .type = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+    };</span><br><span style="color: hsl(120, 100%, 40%);">+    struct pcap_ipv4_header pcap_ipv4_header = {</span><br><span style="color: hsl(120, 100%, 40%);">+          .ver_ihl = 0x45, /* IPv4 + 20 bytes of header */</span><br><span style="color: hsl(120, 100%, 40%);">+              .ip_ttl = 128, /* We always put a TTL of 128 to keep Wireshark less blue */</span><br><span style="color: hsl(120, 100%, 40%);">+   };</span><br><span style="color: hsl(120, 100%, 40%);">+    struct pcap_ipv6_header pcap_ipv6_header = {</span><br><span style="color: hsl(120, 100%, 40%);">+          .ip6_ctlun.ip6_un2_vfc = 0x60,</span><br><span style="color: hsl(120, 100%, 40%);">+        };</span><br><span style="color: hsl(120, 100%, 40%);">+    void *pcap_ip_header;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t pcap_ip_header_len;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct pcap_udp_header pcap_udp_header;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Packets are always stored as UDP to simplify this logic */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (source) {</span><br><span style="color: hsl(120, 100%, 40%);">+         pcap_udp_header.src = ntohs(pj_sockaddr_get_port(source));</span><br><span style="color: hsl(120, 100%, 40%);">+    } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              pcap_udp_header.src = ntohs(0);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (destination) {</span><br><span style="color: hsl(120, 100%, 40%);">+            pcap_udp_header.dst = ntohs(pj_sockaddr_get_port(destination));</span><br><span style="color: hsl(120, 100%, 40%);">+       } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              pcap_udp_header.dst = ntohs(0);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     pcap_udp_header.length = ntohs(sizeof(struct pcap_udp_header) + msg_len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Construct the appropriate IP header */</span><br><span style="color: hsl(120, 100%, 40%);">+     if ((source && source->addr.sa_family == pj_AF_INET()) ||</span><br><span style="color: hsl(120, 100%, 40%);">+          (destination && destination->addr.sa_family == pj_AF_INET())) {</span><br><span style="color: hsl(120, 100%, 40%);">+            pcap_ethernet_header.type = htons(0x0800); /* We are providing an IPv4 packet */</span><br><span style="color: hsl(120, 100%, 40%);">+              pcap_ip_header = &pcap_ipv4_header;</span><br><span style="color: hsl(120, 100%, 40%);">+               pcap_ip_header_len = sizeof(struct pcap_ipv4_header);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (source) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 memcpy(&pcap_ipv4_header.ip_src, pj_sockaddr_get_addr(source), pj_sockaddr_get_addr_len(source));</span><br><span style="color: hsl(120, 100%, 40%);">+         }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (destination) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    memcpy(&pcap_ipv4_header.ip_dst, pj_sockaddr_get_addr(destination), pj_sockaddr_get_addr_len(destination));</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+             pcap_ipv4_header.ip_len = htons(sizeof(struct pcap_udp_header) + sizeof(struct pcap_ipv4_header) + msg_len);</span><br><span style="color: hsl(120, 100%, 40%);">+          pcap_ipv4_header.ip_protocol = IPPROTO_UDP; /* We always provide UDP */</span><br><span style="color: hsl(120, 100%, 40%);">+       } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              pcap_ethernet_header.type = htons(0x86DD); /* We are providing an IPv6 packet */</span><br><span style="color: hsl(120, 100%, 40%);">+              pcap_ip_header = &pcap_ipv6_header;</span><br><span style="color: hsl(120, 100%, 40%);">+               pcap_ip_header_len = sizeof(struct pcap_ipv6_header);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (source) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 memcpy(&pcap_ipv6_header.ip6_src, pj_sockaddr_get_addr(source), pj_sockaddr_get_addr_len(source));</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (destination) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    memcpy(&pcap_ipv6_header.ip6_dst, pj_sockaddr_get_addr(destination), pj_sockaddr_get_addr_len(destination));</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+             pcap_ipv6_header.ip6_ctlun.ip6_un1.ip6_un1_plen = htons(sizeof(struct pcap_udp_header) + msg_len);</span><br><span style="color: hsl(120, 100%, 40%);">+            pcap_ipv6_header.ip6_ctlun.ip6_un1.ip6_un1_nxt = IPPROTO_UDP;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Add up all the sizes for this record */</span><br><span style="color: hsl(120, 100%, 40%);">+    pcap_record_header.incl_len = pcap_record_header.orig_len = sizeof(pcap_ethernet_header) + pcap_ip_header_len + sizeof(pcap_udp_header) + msg_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* We lock the logger session since we're writing these out in parts */</span><br><span style="color: hsl(120, 100%, 40%);">+   ao2_wrlock(session);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (session->pcap_file) {</span><br><span style="color: hsl(120, 100%, 40%);">+          if (fwrite(&pcap_record_header, sizeof(struct pcap_record_header), 1, session->pcap_file) != sizeof(struct pcap_record_header)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      ast_log(LOG_WARNING, "Writing PCAP header failed: %s\n", strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+          }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (fwrite(&pcap_ethernet_header, sizeof(struct pcap_ethernet_header), 1, session->pcap_file) != sizeof(struct pcap_ethernet_header)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        ast_log(LOG_WARNING, "Writing ethernet header to pcap failed: %s\n", strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (fwrite(pcap_ip_header, pcap_ip_header_len, 1, session->pcap_file) != pcap_ip_header_len) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     ast_log(LOG_WARNING, "Writing IP header to pcap failed: %s\n", strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (fwrite(&pcap_udp_header, sizeof(struct pcap_udp_header), 1, session->pcap_file) != sizeof(struct pcap_udp_header)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       ast_log(LOG_WARNING, "Writing UDP header to pcap failed: %s\n", strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (fwrite(msg, msg_len, 1, session->pcap_file) != msg_len) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      ast_log(LOG_WARNING, "Writing UDP payload to pcap failed: %s\n", strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+          }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     ao2_unlock(session);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata)</span><br><span> {</span><br><span>         char buffer[AST_SOCKADDR_BUFLEN];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (!pjsip_log_test_addr(tdata->tp_info.dst_name, tdata->tp_info.dst_port)) {</span><br><span style="color: hsl(120, 100%, 40%);">+   ao2_rdlock(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!pjsip_log_test_addr(default_logger, tdata->tp_info.dst_name, tdata->tp_info.dst_port)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ao2_unlock(default_logger);</span><br><span>          return PJ_SUCCESS;</span><br><span>   }</span><br><span style="color: hsl(120, 100%, 40%);">+     ao2_unlock(default_logger);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ast_verbose("<--- Transmitting SIP %s (%d bytes) to %s:%s --->\n%.*s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                    tdata->msg->type == PJSIP_REQUEST_MSG ? "request" : "response",</span><br><span style="color: hsl(0, 100%, 40%);">-               (int) (tdata->buf.cur - tdata->buf.start),</span><br><span style="color: hsl(0, 100%, 40%);">-                tdata->tp_info.transport->type_name,</span><br><span style="color: hsl(0, 100%, 40%);">-              pj_sockaddr_print(&tdata->tp_info.dst_addr, buffer, sizeof(buffer), 3),</span><br><span style="color: hsl(0, 100%, 40%);">-                  (int) (tdata->buf.end - tdata->buf.start), tdata->buf.start);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (default_logger->log_to_verbose) {</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_verbose("<--- Transmitting SIP %s (%d bytes) to %s:%s --->\n%.*s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                      tdata->msg->type == PJSIP_REQUEST_MSG ? "request" : "response",</span><br><span style="color: hsl(120, 100%, 40%);">+                     (int) (tdata->buf.cur - tdata->buf.start),</span><br><span style="color: hsl(120, 100%, 40%);">+                      tdata->tp_info.transport->type_name,</span><br><span style="color: hsl(120, 100%, 40%);">+                    pj_sockaddr_print(&tdata->tp_info.dst_addr, buffer, sizeof(buffer), 3),</span><br><span style="color: hsl(120, 100%, 40%);">+                        (int) (tdata->buf.end - tdata->buf.start), tdata->buf.start);</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (default_logger->log_to_pcap) {</span><br><span style="color: hsl(120, 100%, 40%);">+         pjsip_logger_write_to_pcap(default_logger, tdata->buf.start, (int) (tdata->buf.end - tdata->buf.start),</span><br><span style="color: hsl(120, 100%, 40%);">+                      NULL, &tdata->tp_info.dst_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  return PJ_SUCCESS;</span><br><span> }</span><br><span> </span><br><span>@@ -93,20 +297,31 @@</span><br><span> {</span><br><span>      char buffer[AST_SOCKADDR_BUFLEN];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (!pjsip_log_test_addr(rdata->pkt_info.src_name, rdata->pkt_info.src_port)) {</span><br><span style="color: hsl(0, 100%, 40%);">-           return PJ_FALSE;</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    if (!rdata->msg_info.msg) {</span><br><span>               return PJ_FALSE;</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ast_verbose("<--- Received SIP %s (%d bytes) from %s:%s --->\n%s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                rdata->msg_info.msg->type == PJSIP_REQUEST_MSG ? "request" : "response",</span><br><span style="color: hsl(0, 100%, 40%);">-              rdata->msg_info.len,</span><br><span style="color: hsl(0, 100%, 40%);">-                 rdata->tp_info.transport->type_name,</span><br><span style="color: hsl(0, 100%, 40%);">-              pj_sockaddr_print(&rdata->pkt_info.src_addr, buffer, sizeof(buffer), 3),</span><br><span style="color: hsl(0, 100%, 40%);">-                 rdata->pkt_info.packet);</span><br><span style="color: hsl(120, 100%, 40%);">+       ao2_rdlock(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!pjsip_log_test_addr(default_logger, rdata->pkt_info.src_name, rdata->pkt_info.src_port)) {</span><br><span style="color: hsl(120, 100%, 40%);">+         ao2_unlock(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+           return PJ_FALSE;</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+     ao2_unlock(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (default_logger->log_to_verbose) {</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_verbose("<--- Received SIP %s (%d bytes) from %s:%s --->\n%s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                  rdata->msg_info.msg->type == PJSIP_REQUEST_MSG ? "request" : "response",</span><br><span style="color: hsl(120, 100%, 40%);">+                    rdata->msg_info.len,</span><br><span style="color: hsl(120, 100%, 40%);">+                       rdata->tp_info.transport->type_name,</span><br><span style="color: hsl(120, 100%, 40%);">+                    pj_sockaddr_print(&rdata->pkt_info.src_addr, buffer, sizeof(buffer), 3),</span><br><span style="color: hsl(120, 100%, 40%);">+                       rdata->pkt_info.packet);</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (default_logger->log_to_pcap) {</span><br><span style="color: hsl(120, 100%, 40%);">+         pjsip_logger_write_to_pcap(default_logger, rdata->pkt_info.packet, rdata->msg_info.len,</span><br><span style="color: hsl(120, 100%, 40%);">+                 &rdata->pkt_info.src_addr, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  return PJ_FALSE;</span><br><span> }</span><br><span> </span><br><span>@@ -119,14 +334,135 @@</span><br><span>   .on_tx_response = logging_on_tx_msg,</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static char *pjsip_enable_logger_host(int fd, const char *arg)</span><br><span style="color: hsl(120, 100%, 40%);">+static char *pjsip_enable_logger_all(int fd)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_sockaddr_resolve_first_af(&log_addr, arg, 0, AST_AF_UNSPEC)) {</span><br><span style="color: hsl(0, 100%, 40%);">-              return CLI_SHOWUSAGE;</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_wrlock(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+   default_logger->enabled = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+       default_logger->log_all_traffic = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+       ao2_unlock(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (fd >= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_cli(fd, "PJSIP Logging enabled\n");</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ast_cli(fd, "PJSIP Logging Enabled for host: %s\n", ast_sockaddr_stringify_addr(&log_addr));</span><br><span style="color: hsl(0, 100%, 40%);">-      logging_mode = LOGGING_MODE_ENABLED;</span><br><span style="color: hsl(120, 100%, 40%);">+  return CLI_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static char *pjsip_enable_logger_host(int fd, const char *arg, unsigned int add_host)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    const char *host = arg;</span><br><span style="color: hsl(120, 100%, 40%);">+       char *mask;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct ast_sockaddr address;</span><br><span style="color: hsl(120, 100%, 40%);">+  int error = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      ao2_wrlock(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+   default_logger->enabled = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!add_host) {</span><br><span style="color: hsl(120, 100%, 40%);">+              /* If this is not adding an additional host or subnet then we have to</span><br><span style="color: hsl(120, 100%, 40%);">+          * remove what already exists.</span><br><span style="color: hsl(120, 100%, 40%);">+                 */</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_free_ha(default_logger->matches);</span><br><span style="color: hsl(120, 100%, 40%);">+              default_logger->matches = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   mask = strrchr(host, '/');</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!mask && !ast_sockaddr_parse(&address, arg, 0)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             if (ast_sockaddr_resolve_first_af(&address, arg, 0, AST_AF_UNSPEC)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     ao2_unlock(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+                   return CLI_SHOWUSAGE;</span><br><span style="color: hsl(120, 100%, 40%);">+         }</span><br><span style="color: hsl(120, 100%, 40%);">+             host = ast_sockaddr_stringify(&address);</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   default_logger->matches = ast_append_ha_with_port("d", host, default_logger->matches, &error);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!default_logger->matches || error) {</span><br><span style="color: hsl(120, 100%, 40%);">+           if (fd >= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     ast_cli(fd, "Failed to add address '%s' for logging\n", host);</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+             ao2_unlock(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+           return CLI_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ao2_unlock(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (fd >= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_cli(fd, "PJSIP Logging Enabled for host: %s\n", ast_sockaddr_stringify_addr(&address));</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return CLI_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static char *pjsip_disable_logger(int fd)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        ao2_wrlock(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Default the settings back to the way they were */</span><br><span style="color: hsl(120, 100%, 40%);">+  default_logger->enabled = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+       default_logger->log_all_traffic = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+       default_logger->pcap_filename[0] = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+   default_logger->log_to_verbose = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+        default_logger->log_to_pcap = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Stop logging to the PCAP file if active */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (default_logger->pcap_file) {</span><br><span style="color: hsl(120, 100%, 40%);">+           fclose(default_logger->pcap_file);</span><br><span style="color: hsl(120, 100%, 40%);">+         default_logger->pcap_file = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_free_ha(default_logger->matches);</span><br><span style="color: hsl(120, 100%, 40%);">+      default_logger->matches = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  ao2_unlock(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (fd >= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_cli(fd, "PJSIP Logging disabled\n");</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return CLI_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static char *pjsip_set_logger_verbose(int fd, const char *arg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   ao2_wrlock(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+   default_logger->log_to_verbose = ast_true(arg);</span><br><span style="color: hsl(120, 100%, 40%);">+    ao2_unlock(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_cli(fd, "PJSIP Logging to verbose has been %s\n", ast_true(arg) ? "enabled" : "disabled");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return CLI_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static char *pjsip_set_logger_pcap(int fd, const char *arg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct pcap_header pcap_header = {</span><br><span style="color: hsl(120, 100%, 40%);">+            .magic_number = 0xa1b2c3d4,</span><br><span style="color: hsl(120, 100%, 40%);">+           .version_major = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+           .version_minor = 4,</span><br><span style="color: hsl(120, 100%, 40%);">+           .snaplen = 65535,</span><br><span style="color: hsl(120, 100%, 40%);">+             .network = 1, /* We always use ethernet so we can combine IPv4 and IPv6 in same pcap */</span><br><span style="color: hsl(120, 100%, 40%);">+       };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  ao2_wrlock(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_copy_string(default_logger->pcap_filename, arg, sizeof(default_logger->pcap_filename));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (default_logger->pcap_file) {</span><br><span style="color: hsl(120, 100%, 40%);">+           fclose(default_logger->pcap_file);</span><br><span style="color: hsl(120, 100%, 40%);">+         default_logger->pcap_file = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   default_logger->pcap_file = fopen(arg, "wb");</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!default_logger->pcap_file) {</span><br><span style="color: hsl(120, 100%, 40%);">+          ao2_unlock(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_cli(fd, "Failed to open file '%s' for pcap writing\n", arg);</span><br><span style="color: hsl(120, 100%, 40%);">+            return CLI_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     fwrite(&pcap_header, 1, sizeof(struct pcap_header), default_logger->pcap_file);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      default_logger->log_to_pcap = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+   ao2_unlock(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_cli(fd, "PJSIP logging to pcap file '%s'\n", arg);</span><br><span> </span><br><span>         return CLI_SUCCESS;</span><br><span> }</span><br><span>@@ -136,9 +472,9 @@</span><br><span>       const char *what;</span><br><span> </span><br><span>        if (cmd == CLI_INIT) {</span><br><span style="color: hsl(0, 100%, 40%);">-          e->command = "pjsip set logger {on|off|host}";</span><br><span style="color: hsl(120, 100%, 40%);">+           e->command = "pjsip set logger {on|off|host|add|verbose|pcap}";</span><br><span>                 e->usage =</span><br><span style="color: hsl(0, 100%, 40%);">-                   "Usage: pjsip set logger {on|off|host <name>}\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                      "Usage: pjsip set logger {on|off|host <name/subnet>|add <name/subnet>|verbose <on/off>|pcap <filename>}\n"</span><br><span>                         "       Enables or disabling logging of SIP packets\n"</span><br><span>                     "       read on ports bound to PJSIP transports either\n"</span><br><span>                  "       globally or enables logging for an individual\n"</span><br><span>@@ -152,18 +488,19 @@</span><br><span> </span><br><span>       if (a->argc == e->args) {        /* on/off */</span><br><span>          if (!strcasecmp(what, "on")) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        logging_mode = LOGGING_MODE_ENABLED;</span><br><span style="color: hsl(0, 100%, 40%);">-                    ast_cli(a->fd, "PJSIP Logging enabled\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                 ast_sockaddr_setnull(&log_addr);</span><br><span style="color: hsl(0, 100%, 40%);">-                    return CLI_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+                   return pjsip_enable_logger_all(a->fd);</span><br><span>            } else if (!strcasecmp(what, "off")) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        logging_mode = LOGGING_MODE_DISABLED;</span><br><span style="color: hsl(0, 100%, 40%);">-                   ast_cli(a->fd, "PJSIP Logging disabled\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                        return CLI_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+                   return pjsip_disable_logger(a->fd);</span><br><span>               }</span><br><span>    } else if (a->argc == e->args + 1) {</span><br><span>           if (!strcasecmp(what, "host")) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      return pjsip_enable_logger_host(a->fd, a->argv[e->args]);</span><br><span style="color: hsl(120, 100%, 40%);">+                    return pjsip_enable_logger_host(a->fd, a->argv[e->args], 0);</span><br><span style="color: hsl(120, 100%, 40%);">+         } else if (!strcasecmp(what, "add")) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      return pjsip_enable_logger_host(a->fd, a->argv[e->args], 1);</span><br><span style="color: hsl(120, 100%, 40%);">+         } else if (!strcasecmp(what, "verbose")) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  return pjsip_set_logger_verbose(a->fd, a->argv[e->args]);</span><br><span style="color: hsl(120, 100%, 40%);">+            } else if (!strcasecmp(what, "pcap")) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     return pjsip_set_logger_pcap(a->fd, a->argv[e->args]);</span><br><span>              }</span><br><span>    }</span><br><span> </span><br><span>@@ -179,19 +516,16 @@</span><br><span>        RAII_VAR(char *, debug, ast_sip_get_debug(), ast_free);</span><br><span> </span><br><span>  if (ast_false(debug)) {</span><br><span style="color: hsl(0, 100%, 40%);">-         logging_mode = LOGGING_MODE_DISABLED;</span><br><span style="color: hsl(120, 100%, 40%);">+         pjsip_disable_logger(-1);</span><br><span>            return;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   logging_mode = LOGGING_MODE_ENABLED;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>         if (ast_true(debug)) {</span><br><span style="color: hsl(0, 100%, 40%);">-          ast_sockaddr_setnull(&log_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+          pjsip_enable_logger_all(-1);</span><br><span>                 return;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* assume host */</span><br><span style="color: hsl(0, 100%, 40%);">-       if (ast_sockaddr_resolve_first_af(&log_addr, debug, 0, AST_AF_UNSPEC)) {</span><br><span style="color: hsl(120, 100%, 40%);">+  if (pjsip_enable_logger_host(-1, debug, 0) != CLI_SUCCESS) {</span><br><span>                 ast_log(LOG_WARNING, "Could not resolve host %s for debug "</span><br><span>                        "logging\n", debug);</span><br><span>       }</span><br><span>@@ -213,6 +547,14 @@</span><br><span>             return AST_MODULE_LOAD_DECLINE;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ default_logger = pjsip_logger_session_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!default_logger) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ast_sorcery_observer_remove(</span><br><span style="color: hsl(120, 100%, 40%);">+                  ast_sip_get_sorcery(), "global", &global_observer);</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_log(LOG_WARNING, "Unable to create default logger\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          return AST_MODULE_LOAD_DECLINE;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  check_debug();</span><br><span> </span><br><span>   ast_sip_register_service(&logging_module);</span><br><span>@@ -229,6 +571,9 @@</span><br><span>         ast_sorcery_observer_remove(</span><br><span>                 ast_sip_get_sorcery(), "global", &global_observer);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_cleanup(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+  default_logger = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     return 0;</span><br><span> }</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/14441">change 14441</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/14441"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 16 </div>
<div style="display:none"> Gerrit-Change-Id: If5859161a72b0d7dd2d1f92d45bed88e0cd07d0e </div>
<div style="display:none"> Gerrit-Change-Number: 14441 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>