Asterisk - The Open Source Telephony Project  18.5.0
res_pjsip_logger.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Mark Michelson <[email protected]>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*** MODULEINFO
20  <depend>pjproject</depend>
21  <depend>res_pjsip</depend>
22  <defaultenabled>yes</defaultenabled>
23  <support_level>core</support_level>
24  ***/
25 
26 #include "asterisk.h"
27 
28 #include <netinet/in.h> /* For IPPROTO_UDP and in6_addr */
29 
30 #include <pjsip.h>
31 
32 #include "asterisk/res_pjsip.h"
33 #include "asterisk/module.h"
34 #include "asterisk/logger.h"
35 #include "asterisk/cli.h"
36 #include "asterisk/netsock2.h"
37 #include "asterisk/acl.h"
38 
39 /*! \brief PCAP Header */
40 struct pcap_header {
41  uint32_t magic_number; /*! \brief PCAP file format magic number */
42  uint16_t version_major; /*! \brief Major version number of the file format */
43  uint16_t version_minor; /*! \brief Minor version number of the file format */
44  int32_t thiszone; /*! \brief GMT to local correction */
45  uint32_t sigfigs; /*! \brief Accuracy of timestamps */
46  uint32_t snaplen; /*! \brief The maximum size that can be recorded in the file */
47  uint32_t network; /*! \brief Type of packets held within the file */
48 };
49 
50 /*! \brief PCAP Packet Record Header */
52  uint32_t ts_sec; /*! \brief When the record was created */
53  uint32_t ts_usec; /*! \brief When the record was created */
54  uint32_t incl_len; /*! \brief Length of packet as saved in the file */
55  uint32_t orig_len; /*! \brief Length of packet as sent over network */
56 };
57 
58 /*! \brief PCAP Ethernet Header */
60  uint8_t dst[6]; /*! \brief Destination MAC address */
61  uint8_t src[6]; /*! \brief Source MAD address */
62  uint16_t type; /*! \brief The type of packet contained within */
63 } __attribute__((__packed__));
64 
65 /*! \brief PCAP IPv4 Header */
67  uint8_t ver_ihl; /*! \brief IP header version and other bits */
68  uint8_t ip_tos; /*! \brief Type of service details */
69  uint16_t ip_len; /*! \brief Total length of the packet (including IPv4 header) */
70  uint16_t ip_id; /*! \brief Identification value */
71  uint16_t ip_off; /*! \brief Fragment offset */
72  uint8_t ip_ttl; /*! \brief Time to live for the packet */
73  uint8_t ip_protocol; /*! \brief Protocol of the data held within the packet (always UDP) */
74  uint16_t ip_sum; /*! \brief Checksum (not calculated for our purposes */
75  uint32_t ip_src; /*! \brief Source IP address */
76  uint32_t ip_dst; /*! \brief Destination IP address */
77 };
78 
79 /*! \brief PCAP IPv6 Header */
81  union {
82  struct ip6_hdrctl {
83  uint32_t ip6_un1_flow; /*! \brief Version, traffic class, flow label */
84  uint16_t ip6_un1_plen; /*! \brief Length of the packet (not including IPv6 header) */
85  uint8_t ip6_un1_nxt; /*! \brief Next header field */
86  uint8_t ip6_un1_hlim; /*! \brief Hop Limit */
87  } ip6_un1;
88  uint8_t ip6_un2_vfc; /*! \brief Version, traffic class */
89  } ip6_ctlun;
90  struct in6_addr ip6_src; /*! \brief Source IP address */
91  struct in6_addr ip6_dst; /*! \brief Destination IP address */
92 };
93 
94 /*! \brief PCAP UDP Header */
96  uint16_t src; /*! \brief Source IP port */
97  uint16_t dst; /*! \brief Destination IP port */
98  uint16_t length; /*! \brief Length of the UDP header plus UDP packet */
99  uint16_t checksum; /*! \brief Packet checksum, left uncalculated for our purposes */
100 };
101 
102 /*! \brief PJSIP Logging Session */
104  /*! \brief Explicit addresses or ranges being logged */
105  struct ast_ha *matches;
106  /*! \brief Filename used for the pcap file */
107  char pcap_filename[PATH_MAX];
108  /*! \brief The pcap file itself */
109  FILE *pcap_file;
110  /*! \brief Whether the session is enabled or not */
111  unsigned int enabled:1;
112  /*! \brief Whether the session is logging all traffic or not */
113  unsigned int log_all_traffic:1;
114  /*! \brief Whether to log to verbose or not */
115  unsigned int log_to_verbose:1;
116  /*! \brief Whether to log to pcap or not */
117  unsigned int log_to_pcap:1;
118 };
119 
120 /*! \brief The default logger session */
122 
123 /*! \brief Destructor for logger session */
124 static void pjsip_logger_session_destroy(void *obj)
125 {
126  struct pjsip_logger_session *session = obj;
127 
128  if (session->pcap_file) {
129  fclose(session->pcap_file);
130  }
131 
132  ast_free_ha(session->matches);
133 }
134 
135 /*! \brief Allocator for logger session */
137 {
139 
142  if (!session) {
143  return NULL;
144  }
145 
146  session->log_to_verbose = 1;
147 
148  return session;
149 }
150 
151 /*! \brief See if we pass debug IP filter */
152 static inline int pjsip_log_test_addr(const struct pjsip_logger_session *session, const char *address, int port)
153 {
154  struct ast_sockaddr test_addr;
155 
156  if (!session->enabled) {
157  return 0;
158  }
159 
160  if (session->log_all_traffic) {
161  return 1;
162  }
163 
164  /* A null address was passed in or no explicit matches. Just reject it. */
165  if (ast_strlen_zero(address) || !session->matches) {
166  return 0;
167  }
168 
169  ast_sockaddr_parse(&test_addr, address, PARSE_PORT_IGNORE);
170  ast_sockaddr_set_port(&test_addr, port);
171 
172  /* Compare the address against the matches */
173  if (ast_apply_ha(session->matches, &test_addr) != AST_SENSE_ALLOW) {
174  return 1;
175  } else {
176  return 0;
177  }
178 }
179 
180 static void pjsip_logger_write_to_pcap(struct pjsip_logger_session *session, const char *msg, size_t msg_len,
181  pj_sockaddr *source, pj_sockaddr *destination)
182 {
183  struct timeval now = ast_tvnow();
184  struct pcap_record_header pcap_record_header = {
185  .ts_sec = now.tv_sec,
186  .ts_usec = now.tv_usec,
187  };
188  struct pcap_ethernet_header pcap_ethernet_header = {
189  .type = 0,
190  };
191  struct pcap_ipv4_header pcap_ipv4_header = {
192  .ver_ihl = 0x45, /* IPv4 + 20 bytes of header */
193  .ip_ttl = 128, /* We always put a TTL of 128 to keep Wireshark less blue */
194  };
195  struct pcap_ipv6_header pcap_ipv6_header = {
196  .ip6_ctlun.ip6_un2_vfc = 0x60,
197  };
198  void *pcap_ip_header;
199  size_t pcap_ip_header_len;
200  struct pcap_udp_header pcap_udp_header;
201 
202  /* Packets are always stored as UDP to simplify this logic */
203  if (source) {
204  pcap_udp_header.src = ntohs(pj_sockaddr_get_port(source));
205  } else {
206  pcap_udp_header.src = ntohs(0);
207  }
208  if (destination) {
209  pcap_udp_header.dst = ntohs(pj_sockaddr_get_port(destination));
210  } else {
211  pcap_udp_header.dst = ntohs(0);
212  }
213  pcap_udp_header.length = ntohs(sizeof(struct pcap_udp_header) + msg_len);
214 
215  /* Construct the appropriate IP header */
216  if ((source && source->addr.sa_family == pj_AF_INET()) ||
217  (destination && destination->addr.sa_family == pj_AF_INET())) {
218  pcap_ethernet_header.type = htons(0x0800); /* We are providing an IPv4 packet */
219  pcap_ip_header = &pcap_ipv4_header;
220  pcap_ip_header_len = sizeof(struct pcap_ipv4_header);
221  if (source) {
222  memcpy(&pcap_ipv4_header.ip_src, pj_sockaddr_get_addr(source), pj_sockaddr_get_addr_len(source));
223  }
224  if (destination) {
225  memcpy(&pcap_ipv4_header.ip_dst, pj_sockaddr_get_addr(destination), pj_sockaddr_get_addr_len(destination));
226  }
227  pcap_ipv4_header.ip_len = htons(sizeof(struct pcap_udp_header) + sizeof(struct pcap_ipv4_header) + msg_len);
228  pcap_ipv4_header.ip_protocol = IPPROTO_UDP; /* We always provide UDP */
229  } else {
230  pcap_ethernet_header.type = htons(0x86DD); /* We are providing an IPv6 packet */
231  pcap_ip_header = &pcap_ipv6_header;
232  pcap_ip_header_len = sizeof(struct pcap_ipv6_header);
233  if (source) {
234  memcpy(&pcap_ipv6_header.ip6_src, pj_sockaddr_get_addr(source), pj_sockaddr_get_addr_len(source));
235  }
236  if (destination) {
237  memcpy(&pcap_ipv6_header.ip6_dst, pj_sockaddr_get_addr(destination), pj_sockaddr_get_addr_len(destination));
238  }
239  pcap_ipv6_header.ip6_ctlun.ip6_un1.ip6_un1_plen = htons(sizeof(struct pcap_udp_header) + msg_len);
240  pcap_ipv6_header.ip6_ctlun.ip6_un1.ip6_un1_nxt = IPPROTO_UDP;
241  }
242 
243  /* Add up all the sizes for this record */
244  pcap_record_header.incl_len = pcap_record_header.orig_len = sizeof(pcap_ethernet_header) + pcap_ip_header_len + sizeof(pcap_udp_header) + msg_len;
245 
246  /* We lock the logger session since we're writing these out in parts */
247  ao2_wrlock(session);
248  if (session->pcap_file) {
249  if (fwrite(&pcap_record_header, sizeof(struct pcap_record_header), 1, session->pcap_file) != 1) {
250  ast_log(LOG_WARNING, "Writing PCAP header failed: %s\n", strerror(errno));
251  }
252  if (fwrite(&pcap_ethernet_header, sizeof(struct pcap_ethernet_header), 1, session->pcap_file) != 1) {
253  ast_log(LOG_WARNING, "Writing ethernet header to pcap failed: %s\n", strerror(errno));
254  }
255  if (fwrite(pcap_ip_header, pcap_ip_header_len, 1, session->pcap_file) != 1) {
256  ast_log(LOG_WARNING, "Writing IP header to pcap failed: %s\n", strerror(errno));
257  }
258  if (fwrite(&pcap_udp_header, sizeof(struct pcap_udp_header), 1, session->pcap_file) != 1) {
259  ast_log(LOG_WARNING, "Writing UDP header to pcap failed: %s\n", strerror(errno));
260  }
261  if (fwrite(msg, msg_len, 1, session->pcap_file) != 1) {
262  ast_log(LOG_WARNING, "Writing UDP payload to pcap failed: %s\n", strerror(errno));
263  }
264  }
265  ao2_unlock(session);
266 }
267 
268 static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata)
269 {
270  char buffer[AST_SOCKADDR_BUFLEN];
271 
272  ao2_rdlock(default_logger);
273  if (!pjsip_log_test_addr(default_logger, tdata->tp_info.dst_name, tdata->tp_info.dst_port)) {
274  ao2_unlock(default_logger);
275  return PJ_SUCCESS;
276  }
277  ao2_unlock(default_logger);
278 
279  if (default_logger->log_to_verbose) {
280  ast_verbose("<--- Transmitting SIP %s (%d bytes) to %s:%s --->\n%.*s\n",
281  tdata->msg->type == PJSIP_REQUEST_MSG ? "request" : "response",
282  (int) (tdata->buf.cur - tdata->buf.start),
283  tdata->tp_info.transport->type_name,
284  pj_sockaddr_print(&tdata->tp_info.dst_addr, buffer, sizeof(buffer), 3),
285  (int) (tdata->buf.end - tdata->buf.start), tdata->buf.start);
286  }
287 
288  if (default_logger->log_to_pcap) {
289  pjsip_logger_write_to_pcap(default_logger, tdata->buf.start, (int) (tdata->buf.cur - tdata->buf.start),
290  NULL, &tdata->tp_info.dst_addr);
291  }
292 
293  return PJ_SUCCESS;
294 }
295 
296 static pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata)
297 {
298  char buffer[AST_SOCKADDR_BUFLEN];
299 
300  if (!rdata->msg_info.msg) {
301  return PJ_FALSE;
302  }
303 
304  ao2_rdlock(default_logger);
305  if (!pjsip_log_test_addr(default_logger, rdata->pkt_info.src_name, rdata->pkt_info.src_port)) {
306  ao2_unlock(default_logger);
307  return PJ_FALSE;
308  }
309  ao2_unlock(default_logger);
310 
311  if (default_logger->log_to_verbose) {
312  ast_verbose("<--- Received SIP %s (%d bytes) from %s:%s --->\n%s\n",
313  rdata->msg_info.msg->type == PJSIP_REQUEST_MSG ? "request" : "response",
314  rdata->msg_info.len,
315  rdata->tp_info.transport->type_name,
316  pj_sockaddr_print(&rdata->pkt_info.src_addr, buffer, sizeof(buffer), 3),
317  rdata->pkt_info.packet);
318  }
319 
320  if (default_logger->log_to_pcap) {
321  pjsip_logger_write_to_pcap(default_logger, rdata->pkt_info.packet, rdata->msg_info.len,
322  &rdata->pkt_info.src_addr, NULL);
323  }
324 
325  return PJ_FALSE;
326 }
327 
328 static pjsip_module logging_module = {
329  .name = { "Logging Module", 14 },
330  .priority = 0,
331  .on_rx_request = logging_on_rx_msg,
332  .on_rx_response = logging_on_rx_msg,
333  .on_tx_request = logging_on_tx_msg,
334  .on_tx_response = logging_on_tx_msg,
335 };
336 
337 static char *pjsip_enable_logger_all(int fd)
338 {
339  ao2_wrlock(default_logger);
340  default_logger->enabled = 1;
341  default_logger->log_all_traffic = 1;
342  ao2_unlock(default_logger);
343 
344  if (fd >= 0) {
345  ast_cli(fd, "PJSIP Logging enabled\n");
346  }
347 
348  return CLI_SUCCESS;
349 }
350 
351 static char *pjsip_enable_logger_host(int fd, const char *arg, unsigned int add_host)
352 {
353  const char *host = arg;
354  char *mask;
355  struct ast_sockaddr address;
356  int error = 0;
357 
358  ao2_wrlock(default_logger);
359  default_logger->enabled = 1;
360 
361  if (!add_host) {
362  /* If this is not adding an additional host or subnet then we have to
363  * remove what already exists.
364  */
365  ast_free_ha(default_logger->matches);
366  default_logger->matches = NULL;
367  }
368 
369  mask = strrchr(host, '/');
370  if (!mask && !ast_sockaddr_parse(&address, arg, 0)) {
371  if (ast_sockaddr_resolve_first_af(&address, arg, 0, AST_AF_UNSPEC)) {
372  ao2_unlock(default_logger);
373  return CLI_SHOWUSAGE;
374  }
375  host = ast_sockaddr_stringify(&address);
376  }
377 
378  default_logger->matches = ast_append_ha_with_port("d", host, default_logger->matches, &error);
379  if (!default_logger->matches || error) {
380  if (fd >= 0) {
381  ast_cli(fd, "Failed to add address '%s' for logging\n", host);
382  }
383  ao2_unlock(default_logger);
384  return CLI_SUCCESS;
385  }
386 
387  ao2_unlock(default_logger);
388 
389  if (fd >= 0) {
390  ast_cli(fd, "PJSIP Logging Enabled for host: %s\n", ast_sockaddr_stringify_addr(&address));
391  }
392 
393  return CLI_SUCCESS;
394 }
395 
396 static char *pjsip_disable_logger(int fd)
397 {
398  ao2_wrlock(default_logger);
399 
400  /* Default the settings back to the way they were */
401  default_logger->enabled = 0;
402  default_logger->log_all_traffic = 0;
403  default_logger->pcap_filename[0] = '\0';
404  default_logger->log_to_verbose = 1;
405  default_logger->log_to_pcap = 0;
406 
407  /* Stop logging to the PCAP file if active */
408  if (default_logger->pcap_file) {
409  fclose(default_logger->pcap_file);
410  default_logger->pcap_file = NULL;
411  }
412 
413  ast_free_ha(default_logger->matches);
414  default_logger->matches = NULL;
415 
416  ao2_unlock(default_logger);
417 
418  if (fd >= 0) {
419  ast_cli(fd, "PJSIP Logging disabled\n");
420  }
421 
422  return CLI_SUCCESS;
423 }
424 
425 static char *pjsip_set_logger_verbose(int fd, const char *arg)
426 {
427  ao2_wrlock(default_logger);
428  default_logger->log_to_verbose = ast_true(arg);
429  ao2_unlock(default_logger);
430 
431  ast_cli(fd, "PJSIP Logging to verbose has been %s\n", ast_true(arg) ? "enabled" : "disabled");
432 
433  return CLI_SUCCESS;
434 }
435 
436 static char *pjsip_set_logger_pcap(int fd, const char *arg)
437 {
438  struct pcap_header pcap_header = {
439  .magic_number = 0xa1b2c3d4,
440  .version_major = 2,
441  .version_minor = 4,
442  .snaplen = 65535,
443  .network = 1, /* We always use ethernet so we can combine IPv4 and IPv6 in same pcap */
444  };
445 
446  ao2_wrlock(default_logger);
447  ast_copy_string(default_logger->pcap_filename, arg, sizeof(default_logger->pcap_filename));
448 
449  if (default_logger->pcap_file) {
450  fclose(default_logger->pcap_file);
451  default_logger->pcap_file = NULL;
452  }
453 
454  default_logger->pcap_file = fopen(arg, "wb");
455  if (!default_logger->pcap_file) {
456  ao2_unlock(default_logger);
457  ast_cli(fd, "Failed to open file '%s' for pcap writing\n", arg);
458  return CLI_SUCCESS;
459  }
460  fwrite(&pcap_header, 1, sizeof(struct pcap_header), default_logger->pcap_file);
461 
462  default_logger->log_to_pcap = 1;
463  ao2_unlock(default_logger);
464 
465  ast_cli(fd, "PJSIP logging to pcap file '%s'\n", arg);
466 
467  return CLI_SUCCESS;
468 }
469 
470 static char *pjsip_set_logger(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
471 {
472  const char *what;
473 
474  if (cmd == CLI_INIT) {
475  e->command = "pjsip set logger {on|off|host|add|verbose|pcap}";
476  e->usage =
477  "Usage: pjsip set logger {on|off|host <name/subnet>|add <name/subnet>|verbose <on/off>|pcap <filename>}\n"
478  " Enables or disabling logging of SIP packets\n"
479  " read on ports bound to PJSIP transports either\n"
480  " globally or enables logging for an individual\n"
481  " host.\n";
482  return NULL;
483  } else if (cmd == CLI_GENERATE) {
484  return NULL;
485  }
486 
487  what = a->argv[e->args - 1]; /* Guaranteed to exist */
488 
489  if (a->argc == e->args) { /* on/off */
490  if (!strcasecmp(what, "on")) {
491  return pjsip_enable_logger_all(a->fd);
492  } else if (!strcasecmp(what, "off")) {
493  return pjsip_disable_logger(a->fd);
494  }
495  } else if (a->argc == e->args + 1) {
496  if (!strcasecmp(what, "host")) {
497  return pjsip_enable_logger_host(a->fd, a->argv[e->args], 0);
498  } else if (!strcasecmp(what, "add")) {
499  return pjsip_enable_logger_host(a->fd, a->argv[e->args], 1);
500  } else if (!strcasecmp(what, "verbose")) {
501  return pjsip_set_logger_verbose(a->fd, a->argv[e->args]);
502  } else if (!strcasecmp(what, "pcap")) {
503  return pjsip_set_logger_pcap(a->fd, a->argv[e->args]);
504  }
505  }
506 
507  return CLI_SHOWUSAGE;
508 }
509 
510 static struct ast_cli_entry cli_pjsip[] = {
511  AST_CLI_DEFINE(pjsip_set_logger, "Enable/Disable PJSIP Logger Output")
512 };
513 
514 static void check_debug(void)
515 {
517 
518  if (ast_false(debug)) {
520  return;
521  }
522 
523  if (ast_true(debug)) {
525  return;
526  }
527 
528  if (pjsip_enable_logger_host(-1, debug, 0) != CLI_SUCCESS) {
529  ast_log(LOG_WARNING, "Could not resolve host %s for debug "
530  "logging\n", debug);
531  }
532 }
533 
534 static void global_reloaded(const char *object_type)
535 {
536  check_debug();
537 }
538 
539 static const struct ast_sorcery_observer global_observer = {
541 };
542 
543 static int load_module(void)
544 {
545  if (ast_sorcery_observer_add(ast_sip_get_sorcery(), "global", &global_observer)) {
546  ast_log(LOG_WARNING, "Unable to add global observer\n");
548  }
549 
550  default_logger = pjsip_logger_session_alloc();
551  if (!default_logger) {
553  ast_sip_get_sorcery(), "global", &global_observer);
554  ast_log(LOG_WARNING, "Unable to create default logger\n");
556  }
557 
558  check_debug();
559 
560  ast_sip_register_service(&logging_module);
561  ast_cli_register_multiple(cli_pjsip, ARRAY_LEN(cli_pjsip));
562 
564 }
565 
566 static int unload_module(void)
567 {
568  ast_cli_unregister_multiple(cli_pjsip, ARRAY_LEN(cli_pjsip));
569  ast_sip_unregister_service(&logging_module);
570 
572  ast_sip_get_sorcery(), "global", &global_observer);
573 
574  ao2_cleanup(default_logger);
575  default_logger = NULL;
576 
577  return 0;
578 }
579 
581  .support_level = AST_MODULE_SUPPORT_CORE,
582  .load = load_module,
583  .unload = unload_module,
584  .load_pri = AST_MODPRI_APP_DEPEND,
585  .requires = "res_pjsip",
586 );
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:290
#define AST_SOCKADDR_BUFLEN
Definition: netsock2.h:46
uint16_t version_minor
Major version number of the file format.
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:197
PCAP Header.
Asterisk main include file. File version handling, generic pbx functions.
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
uint32_t ip_src
Checksum (not calculated for our purposes.
static void check_debug(void)
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
char pcap_filename[PATH_MAX]
Filename used for the pcap file.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
unsigned int log_to_verbose
Whether to log to verbose or not.
char * address
Definition: f2c.h:59
uint16_t version_major
PCAP file format magic number.
descriptor for a cli entry.
Definition: cli.h:171
const int argc
Definition: cli.h:160
#define LOG_WARNING
Definition: logger.h:274
uint32_t orig_len
Length of packet as saved in the file.
static int debug
Global debug status.
Definition: res_xmpp.c:435
uint32_t network
The maximum size that can be recorded in the file.
struct in6_addr ip6_dst
Source IP address.
uint16_t dst
Source IP port.
static char * pjsip_set_logger(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
char * ast_sip_get_debug(void)
Retrieve the system debug setting (yes|no|host).
uint16_t type
Source MAD address.
Definition: cli.h:152
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:808
uint8_t ip_ttl
Fragment offset.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
PCAP Packet Record Header.
uint16_t ip_sum
Protocol of the data held within the packet (always UDP)
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
uint32_t incl_len
When the record was created.
uint16_t ip_off
Identification value.
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
static const struct ast_sorcery_observer global_observer
#define ao2_unlock(a)
Definition: astobj2.h:730
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
uint8_t ip_protocol
Time to live for the packet.
#define NULL
Definition: resample.c:96
int32_t thiszone
Minor version number of the file format.
uint16_t checksum
Length of the UDP header plus UDP packet.
#define ao2_wrlock(a)
Definition: astobj2.h:720
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata)
Socket address structure.
Definition: netsock2.h:97
PJSIP Logging Session.
uint32_t sigfigs
GMT to local correction.
static void pjsip_logger_session_destroy(void *obj)
Destructor for logger session.
union pcap_ipv6_header::@483 ip6_ctlun
int args
This gets set in ast_cli_register()
Definition: cli.h:185
#define ast_strlen_zero(foo)
Definition: strings.h:52
uint16_t ip6_un1_plen
Version, traffic class, flow label.
static int load_module(void)
static char * pjsip_disable_logger(int fd)
unsigned int log_to_pcap
Whether to log to pcap or not.
internal representation of ACL entries In principle user applications would have no need for this...
Definition: acl.h:51
uint16_t length
Destination IP port.
uint16_t ip_len
Type of service details.
#define ast_log
Definition: astobj2.c:42
static pjsip_module logging_module
static char host[256]
Definition: muted.c:77
static char * pjsip_set_logger_pcap(int fd, const char *arg)
uint32_t ts_usec
When the record was created.
#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:911
uint32_t ip_dst
Source IP address.
const int fd
Definition: cli.h:159
static void global_reloaded(const char *object_type)
static struct ast_mansession session
Access Control of various sorts.
uint8_t ip6_un1_nxt
Length of the packet (not including IPv6 header)
PCAP IPv6 Header.
PCAP IPv4 Header.
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.
Definition: netsock2.c:337
uint32_t snaplen
Accuracy of timestamps.
struct pcap_ipv6_header::@483::ip6_hdrctl ip6_un1
int ast_sip_register_service(pjsip_module *module)
Register a SIP service in Asterisk.
Definition: res_pjsip.c:3315
Network socket handling.
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.
Definition: sorcery.c:2386
const char *const * argv
Definition: cli.h:161
static struct pjsip_logger_session * pjsip_logger_session_alloc(void)
Allocator for logger session.
static int unload_module(void)
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
static char * pjsip_enable_logger_all(int fd)
Interface for a sorcery object type observer.
Definition: sorcery.h:332
#define ao2_rdlock(a)
Definition: astobj2.h:719
int errno
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
static struct ast_cli_entry cli_pjsip[]
uint8_t ip_tos
IP header version and other bits.
#define ast_free(a)
Definition: astmm.h:182
char * command
Definition: cli.h:186
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
uint32_t magic_number
struct in6_addr ip6_src
void(* loaded)(const char *object_type)
Callback for when an object type is loaded/reloaded.
Definition: sorcery.h:343
Support for logging to various files, console and syslog Configuration in file logger.conf.
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
const char * usage
Definition: cli.h:177
static char * pjsip_enable_logger_host(int fd, const char *arg, unsigned int add_host)
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
Definition: acl.c:222
#define CLI_SUCCESS
Definition: cli.h:44
static char * pjsip_set_logger_verbose(int fd, const char *arg)
static struct pjsip_logger_session * default_logger
The default logger session.
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.
Definition: sorcery.c:2418
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:718
FILE * pcap_file
The pcap file itself.
unsigned int enabled
Whether the session is enabled or not.
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Standard Command Line Interface.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static int pjsip_log_test_addr(const struct pjsip_logger_session *session, const char *address, int port)
See if we pass debug IP filter.
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)
unsigned int log_all_traffic
Whether the session is logging all traffic or not.
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
Definition: main/utils.c:1968
void ast_sip_unregister_service(pjsip_module *module)
Definition: res_pjsip.c:3331
struct ast_ha * matches
Explicit addresses or ranges being logged.
int error(const char *format,...)
Definition: utils/frame.c:999
#define PATH_MAX
Definition: asterisk.h:40
int int32_t
Definition: db.h:60
PCAP UDP Header.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Asterisk module definitions.
uint16_t ip_id
Total length of the packet (including IPv4 header)
uint8_t ip6_un1_hlim
Next header field.
static pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata)
PCAP Ethernet Header.
static struct test_val a