Wed Jan 8 2020 09:50:21

Asterisk developer's documentation


stun.c File Reference

STUN Support. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/stun.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/channel.h"

Go to the source code of this file.

Data Structures

struct  stun_addr
 
struct  stun_attr
 
struct  stun_header
 
struct  stun_state
 here we store credentials extracted from a message More...
 
struct  stun_trans_id
 STUN support code. More...
 

Macros

#define STUN_BINDERR   0x0111
 
#define STUN_BINDREQ   0x0001
 STUN message types 'BIND' refers to transactions used to determine the externally visible addresses. 'SEC' refers to transactions used to establish a session key for subsequent requests. 'SEC' functionality is not supported here. More...
 
#define STUN_BINDRESP   0x0101
 
#define STUN_CHANGE_REQUEST   0x0003
 
#define STUN_CHANGED_ADDRESS   0x0005
 
#define STUN_ERROR_CODE   0x0009
 
#define STUN_MAPPED_ADDRESS   0x0001
 Basic attribute types in stun messages. Messages can also contain custom attributes (codes above 0x7fff) More...
 
#define STUN_MESSAGE_INTEGRITY   0x0008
 
#define STUN_PASSWORD   0x0007
 
#define STUN_REFLECTED_FROM   0x000b
 
#define STUN_RESPONSE_ADDRESS   0x0002
 
#define STUN_SECERR   0x0112
 
#define STUN_SECREQ   0x0002
 
#define STUN_SECRESP   0x0102
 
#define STUN_SOURCE_ADDRESS   0x0004
 
#define STUN_UNKNOWN_ATTRIBUTES   0x000a
 
#define STUN_USERNAME   0x0006
 

Functions

static void append_attr_address (struct stun_attr **attr, int attrval, struct sockaddr_in *sin, int *len, int *left)
 append an address to an STUN message More...
 
static void append_attr_string (struct stun_attr **attr, int attrval, const char *s, int *len, int *left)
 append a string to an STUN message More...
 
int ast_stun_handle_packet (int s, struct sockaddr_in *src, unsigned char *data, size_t len, stun_cb_f *stun_cb, void *arg)
 handle an incoming STUN message. More...
 
void ast_stun_init (void)
 Initialize the STUN system in Asterisk. More...
 
int ast_stun_request (int s, struct sockaddr_in *dst, const char *username, struct sockaddr_in *answer)
 Generic STUN request. More...
 
static char * handle_cli_stun_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static const char * stun_attr2str (int msg)
 helper function to print attribute names More...
 
static int stun_get_mapped (struct stun_attr *attr, void *arg)
 Extract the STUN_MAPPED_ADDRESS from the stun response. This is used as a callback for stun_handle_response when called from ast_stun_request. More...
 
static int stun_id_cmp (stun_trans_id *left, stun_trans_id *right)
 
static const char * stun_msg2str (int msg)
 helper function to print message names More...
 
static int stun_process_attr (struct stun_state *state, struct stun_attr *attr)
 
static void stun_req_id (struct stun_header *req)
 helper function to generate a random request id More...
 
static int stun_send (int s, struct sockaddr_in *dst, struct stun_header *resp)
 wrapper to send an STUN message More...
 
static void stun_shutdown (void)
 

Variables

static struct ast_cli_entry cli_stun []
 
static int stundebug
 

Detailed Description

STUN Support.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Note
STUN is defined in RFC 3489.

Definition in file stun.c.

Macro Definition Documentation

#define STUN_BINDERR   0x0111

Definition at line 105 of file stun.c.

Referenced by ast_stun_request(), and stun_msg2str().

#define STUN_BINDREQ   0x0001

STUN message types 'BIND' refers to transactions used to determine the externally visible addresses. 'SEC' refers to transactions used to establish a session key for subsequent requests. 'SEC' functionality is not supported here.

Definition at line 103 of file stun.c.

Referenced by ast_stun_handle_packet(), ast_stun_request(), and stun_msg2str().

#define STUN_BINDRESP   0x0101

Definition at line 104 of file stun.c.

Referenced by ast_stun_handle_packet(), ast_stun_request(), and stun_msg2str().

#define STUN_CHANGE_REQUEST   0x0003

Definition at line 115 of file stun.c.

Referenced by stun_attr2str().

#define STUN_CHANGED_ADDRESS   0x0005

Definition at line 117 of file stun.c.

Referenced by stun_attr2str().

#define STUN_ERROR_CODE   0x0009

Definition at line 121 of file stun.c.

Referenced by stun_attr2str().

#define STUN_MAPPED_ADDRESS   0x0001

Basic attribute types in stun messages. Messages can also contain custom attributes (codes above 0x7fff)

Definition at line 113 of file stun.c.

Referenced by ast_stun_handle_packet(), stun_attr2str(), and stun_get_mapped().

#define STUN_MESSAGE_INTEGRITY   0x0008

Definition at line 120 of file stun.c.

Referenced by stun_attr2str().

#define STUN_PASSWORD   0x0007

Definition at line 119 of file stun.c.

Referenced by stun_attr2str(), and stun_process_attr().

#define STUN_REFLECTED_FROM   0x000b

Definition at line 123 of file stun.c.

Referenced by stun_attr2str().

#define STUN_RESPONSE_ADDRESS   0x0002

Definition at line 114 of file stun.c.

Referenced by stun_attr2str().

#define STUN_SECERR   0x0112

Definition at line 108 of file stun.c.

Referenced by stun_msg2str().

#define STUN_SECREQ   0x0002

Definition at line 106 of file stun.c.

Referenced by stun_msg2str().

#define STUN_SECRESP   0x0102

Definition at line 107 of file stun.c.

Referenced by stun_msg2str().

#define STUN_SOURCE_ADDRESS   0x0004

Definition at line 116 of file stun.c.

Referenced by stun_attr2str().

#define STUN_UNKNOWN_ATTRIBUTES   0x000a

Definition at line 122 of file stun.c.

Referenced by stun_attr2str().

#define STUN_USERNAME   0x0006

Definition at line 118 of file stun.c.

Referenced by ast_stun_handle_packet(), ast_stun_request(), stun_attr2str(), and stun_process_attr().

Function Documentation

static void append_attr_address ( struct stun_attr **  attr,
int  attrval,
struct sockaddr_in *  sin,
int *  len,
int *  left 
)
static

append an address to an STUN message

Definition at line 216 of file stun.c.

References stun_addr::addr, stun_addr::family, stun_addr::port, and stun_addr::unused.

Referenced by ast_stun_handle_packet().

217 {
218  int size = sizeof(**attr) + 8;
219  struct stun_addr *addr;
220  if (*left > size) {
221  (*attr)->attr = htons(attrval);
222  (*attr)->len = htons(8);
223  addr = (struct stun_addr *)((*attr)->value);
224  addr->unused = 0;
225  addr->family = 0x01;
226  addr->port = sin->sin_port;
227  addr->addr = sin->sin_addr.s_addr;
228  (*attr) = (struct stun_attr *)((*attr)->value + 8);
229  *len += size;
230  *left -= size;
231  }
232 }
unsigned char unused
Definition: stun.c:90
Definition: stun.c:80
unsigned int addr
Definition: stun.c:93
Definition: stun.c:89
unsigned char family
Definition: stun.c:91
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
unsigned short port
Definition: stun.c:92
static void append_attr_string ( struct stun_attr **  attr,
int  attrval,
const char *  s,
int *  len,
int *  left 
)
static

append a string to an STUN message

Definition at line 202 of file stun.c.

Referenced by ast_stun_handle_packet(), and ast_stun_request().

203 {
204  int size = sizeof(**attr) + strlen(s);
205  if (*left > size) {
206  (*attr)->attr = htons(attrval);
207  (*attr)->len = htons(strlen(s));
208  memcpy((*attr)->value, s, strlen(s));
209  (*attr) = (struct stun_attr *)((*attr)->value + strlen(s));
210  *len += size;
211  *left -= size;
212  }
213 }
Definition: stun.c:80
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int ast_stun_handle_packet ( int  s,
struct sockaddr_in *  src,
unsigned char *  data,
size_t  len,
stun_cb_f stun_cb,
void *  arg 
)

handle an incoming STUN message.

Parameters
sSocket to send any response to.
srcAddress where packet came from.
dataSTUN packet buffer to process.
lenLength of packet
stun_cbIf not NULL, callback for each STUN attribute.
argArg to pass to callback.

Do some basic sanity checks on packet size and content, try to extract a bit of information, and possibly reply. At the moment this only processes BIND requests, and returns the externally visible address of the request. If a callback is specified, invoke it with the attribute.

Return values
AST_STUN_ACCEPTif responed to a STUN request
AST_STUN_IGNORE
-1on error

Definition at line 264 of file stun.c.

References append_attr_address(), append_attr_string(), ast_debug, AST_STUN_ACCEPT, AST_STUN_IGNORE, ast_verbose(), stun_attr::attr, stun_header::id, stun_header::ies, stun_attr::len, stun_header::msglen, stun_header::msgtype, stun_attr2str(), STUN_BINDREQ, STUN_BINDRESP, STUN_MAPPED_ADDRESS, stun_msg2str(), stun_process_attr(), stun_send(), STUN_USERNAME, switch(), and stun_state::username.

Referenced by ast_rtp_read(), and ast_stun_request().

265 {
266  struct stun_header *hdr = (struct stun_header *)data;
267  struct stun_attr *attr;
268  struct stun_state st;
269  int ret = AST_STUN_IGNORE;
270  int x;
271 
272  /* On entry, 'len' is the length of the udp payload. After the
273  * initial checks it becomes the size of unprocessed options,
274  * while 'data' is advanced accordingly.
275  */
276  if (len < sizeof(struct stun_header)) {
277  ast_debug(1, "Runt STUN packet (only %d, wanting at least %d)\n", (int) len, (int) sizeof(struct stun_header));
278  return -1;
279  }
280  len -= sizeof(struct stun_header);
281  data += sizeof(struct stun_header);
282  x = ntohs(hdr->msglen); /* len as advertised in the message */
283  if (stundebug)
284  ast_verbose("STUN Packet, msg %s (%04x), length: %d\n", stun_msg2str(ntohs(hdr->msgtype)), (unsigned)ntohs(hdr->msgtype), x);
285  if (x > len) {
286  ast_debug(1, "Scrambled STUN packet length (got %d, expecting %d)\n", x, (int)len);
287  } else
288  len = x;
289  memset(&st, 0, sizeof(st));
290  while (len) {
291  if (len < sizeof(struct stun_attr)) {
292  ast_debug(1, "Runt Attribute (got %d, expecting %d)\n", (int)len, (int) sizeof(struct stun_attr));
293  break;
294  }
295  attr = (struct stun_attr *)data;
296  /* compute total attribute length */
297  x = ntohs(attr->len) + sizeof(struct stun_attr);
298  if (x > len) {
299  ast_debug(1, "Inconsistent Attribute (length %d exceeds remaining msg len %d)\n", x, (int)len);
300  break;
301  }
302  if (stun_cb)
303  stun_cb(attr, arg);
304  if (stun_process_attr(&st, attr)) {
305  ast_debug(1, "Failed to handle attribute %s (%04x)\n", stun_attr2str(ntohs(attr->attr)), (unsigned)ntohs(attr->attr));
306  break;
307  }
308  /* Clear attribute id: in case previous entry was a string,
309  * this will act as the terminator for the string.
310  */
311  attr->attr = 0;
312  data += x;
313  len -= x;
314  }
315  /* Null terminate any string.
316  * XXX NOTE, we write past the size of the buffer passed by the
317  * caller, so this is potentially dangerous. The only thing that
318  * saves us is that usually we read the incoming message in a
319  * much larger buffer in the struct ast_rtp
320  */
321  *data = '\0';
322 
323  /* Now prepare to generate a reply, which at the moment is done
324  * only for properly formed (len == 0) STUN_BINDREQ messages.
325  */
326  if (len == 0) {
327  unsigned char respdata[1024];
328  struct stun_header *resp = (struct stun_header *)respdata;
329  int resplen = 0; /* len excluding header */
330  int respleft = sizeof(respdata) - sizeof(struct stun_header);
331 
332  resp->id = hdr->id;
333  resp->msgtype = 0;
334  resp->msglen = 0;
335  attr = (struct stun_attr *)resp->ies;
336  switch (ntohs(hdr->msgtype)) {
337  case STUN_BINDREQ:
338  if (stundebug)
339  ast_verbose("STUN Bind Request, username: %s\n",
340  st.username ? st.username : "<none>");
341  if (st.username)
342  append_attr_string(&attr, STUN_USERNAME, st.username, &resplen, &respleft);
343  append_attr_address(&attr, STUN_MAPPED_ADDRESS, src, &resplen, &respleft);
344  resp->msglen = htons(resplen);
345  resp->msgtype = htons(STUN_BINDRESP);
346  stun_send(s, src, resp);
347  ret = AST_STUN_ACCEPT;
348  break;
349  default:
350  if (stundebug)
351  ast_verbose("Dunno what to do with STUN message %04x (%s)\n", (unsigned)ntohs(hdr->msgtype), stun_msg2str(ntohs(hdr->msgtype)));
352  }
353  }
354  return ret;
355 }
unsigned short msglen
Definition: stun.c:75
static const char * stun_msg2str(int msg)
helper function to print message names
Definition: stun.c:126
#define STUN_BINDRESP
Definition: stun.c:104
unsigned short msgtype
Definition: stun.c:74
#define STUN_MAPPED_ADDRESS
Basic attribute types in stun messages. Messages can also contain custom attributes (codes above 0x7f...
Definition: stun.c:113
switch(yytype)
Definition: ast_expr2.c:1510
Definition: stun.c:80
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
#define STUN_USERNAME
Definition: stun.c:118
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static void append_attr_address(struct stun_attr **attr, int attrval, struct sockaddr_in *sin, int *len, int *left)
append an address to an STUN message
Definition: stun.c:216
stun_trans_id id
Definition: stun.c:76
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define STUN_BINDREQ
STUN message types &#39;BIND&#39; refers to transactions used to determine the externally visible addresses...
Definition: stun.c:103
here we store credentials extracted from a message
Definition: stun.c:176
static int stundebug
Definition: stun.c:43
static int stun_process_attr(struct stun_state *state, struct stun_attr *attr)
Definition: stun.c:181
unsigned char ies[0]
Definition: stun.c:77
unsigned short attr
Definition: stun.c:81
static void append_attr_string(struct stun_attr **attr, int attrval, const char *s, int *len, int *left)
append a string to an STUN message
Definition: stun.c:202
unsigned short len
Definition: stun.c:82
static int stun_send(int s, struct sockaddr_in *dst, struct stun_header *resp)
wrapper to send an STUN message
Definition: stun.c:235
static const char * stun_attr2str(int msg)
helper function to print attribute names
Definition: stun.c:146
void ast_stun_init ( void  )

Initialize the STUN system in Asterisk.

Provided by stun.c

Definition at line 508 of file stun.c.

References ast_cli_register_multiple(), ast_register_atexit(), and stun_shutdown().

Referenced by main().

509 {
510  ast_cli_register_multiple(cli_stun, sizeof(cli_stun) / sizeof(struct ast_cli_entry));
512 }
static void stun_shutdown(void)
Definition: stun.c:502
descriptor for a cli entry.
Definition: cli.h:165
static struct ast_cli_entry cli_stun[]
Definition: stun.c:498
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: asterisk.c:998
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
int ast_stun_request ( int  s,
struct sockaddr_in *  dst,
const char *  username,
struct sockaddr_in *  answer 
)

Generic STUN request.

Parameters
sThe socket used to send the request.
dstIf non null, the address of the STUN server. Only needed if the socket is not bound or connected.
usernameIf non null, add the username in the request.
answerIf non null, the function waits for a response and puts here the externally visible address.

Send a generic STUN request to the server specified, possibly waiting for a reply and filling the answer parameter with the externally visible address. Note that in this case the request will be blocking.

Note
The interface may change slightly in the future.
Return values
0on success.
<0on error.
>0on timeout.

Definition at line 373 of file stun.c.

References append_attr_string(), ast_debug, ast_poll, ast_stun_handle_packet(), stun_attr::attr, errno, stun_header::id, stun_header::ies, if(), stun_header::msglen, stun_header::msgtype, STUN_BINDERR, STUN_BINDREQ, STUN_BINDRESP, stun_get_mapped(), stun_id_cmp(), stun_req_id(), stun_send(), and STUN_USERNAME.

Referenced by ast_rtp_stun_request(), gtalk_update_externip(), and stun_monitor_request().

375 {
376  struct stun_header *req;
377  struct stun_header *rsp;
378  unsigned char req_buf[1024];
379  unsigned char rsp_buf[1024];
380  int reqlen, reqleft;
381  struct stun_attr *attr;
382  int res = -1;
383  int retry;
384 
385  if (answer) {
386  /* Always clear answer in case the request fails. */
387  memset(answer, 0, sizeof(struct sockaddr_in));
388  }
389 
390  /* Create STUN bind request */
391  req = (struct stun_header *) req_buf;
392  stun_req_id(req);
393  reqlen = 0;
394  reqleft = sizeof(req_buf) - sizeof(struct stun_header);
395  req->msgtype = 0;
396  req->msglen = 0;
397  attr = (struct stun_attr *) req->ies;
398  if (username) {
399  append_attr_string(&attr, STUN_USERNAME, username, &reqlen, &reqleft);
400  }
401  req->msglen = htons(reqlen);
402  req->msgtype = htons(STUN_BINDREQ);
403 
404  for (retry = 0; retry++ < 3;) { /* XXX make retries configurable */
405  /* send request, possibly wait for reply */
406  struct sockaddr_in src;
407  socklen_t srclen;
408 
409  /* Send STUN message. */
410  res = stun_send(s, dst, req);
411  if (res < 0) {
412  ast_debug(1, "stun_send try %d failed: %s\n", retry, strerror(errno));
413  break;
414  }
415  if (!answer) {
416  /* Successful send since we don't care about any response. */
417  res = 0;
418  break;
419  }
420 
421 try_again:
422  /* Wait for response. */
423  {
424  struct pollfd pfds = { .fd = s, .events = POLLIN };
425 
426  res = ast_poll(&pfds, 1, 3000);
427  if (res < 0) {
428  /* Error */
429  continue;
430  }
431  if (!res) {
432  /* No response, timeout */
433  res = 1;
434  continue;
435  }
436  }
437 
438  /* Read STUN response. */
439  memset(&src, 0, sizeof(src));
440  srclen = sizeof(src);
441  /* XXX pass sizeof(rsp_buf) - 1 in the size, because stun_handle_packet might
442  * write past the end of the buffer.
443  */
444  res = recvfrom(s, rsp_buf, sizeof(rsp_buf) - 1,
445  0, (struct sockaddr *) &src, &srclen);
446  if (res < 0) {
447  ast_debug(1, "recvfrom try %d failed: %s\n", retry, strerror(errno));
448  break;
449  }
450 
451  /* Process the STUN response. */
452  rsp = (struct stun_header *) rsp_buf;
453  if (ast_stun_handle_packet(s, &src, rsp_buf, res, stun_get_mapped, answer)
454  || (rsp->msgtype != htons(STUN_BINDRESP)
455  && rsp->msgtype != htons(STUN_BINDERR))
456  || stun_id_cmp(&req->id, &rsp->id)) {
457  /* Bad STUN packet, not right type, or transaction ID did not match. */
458  memset(answer, 0, sizeof(struct sockaddr_in));
459 
460  /* Was not a resonse to our request. */
461  goto try_again;
462  }
463  /* Success. answer contains the external address if available. */
464  res = 0;
465  break;
466  }
467  return res;
468 }
unsigned short msglen
Definition: stun.c:75
#define STUN_BINDRESP
Definition: stun.c:104
unsigned short msgtype
Definition: stun.c:74
Definition: stun.c:80
int ast_stun_handle_packet(int s, struct sockaddr_in *src, unsigned char *data, size_t len, stun_cb_f *stun_cb, void *arg)
handle an incoming STUN message.
Definition: stun.c:264
#define STUN_USERNAME
Definition: stun.c:118
static int stun_get_mapped(struct stun_attr *attr, void *arg)
Extract the STUN_MAPPED_ADDRESS from the stun response. This is used as a callback for stun_handle_re...
Definition: stun.c:361
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static void stun_req_id(struct stun_header *req)
helper function to generate a random request id
Definition: stun.c:257
#define ast_poll(a, b, c)
Definition: poll-compat.h:88
stun_trans_id id
Definition: stun.c:76
#define STUN_BINDREQ
STUN message types &#39;BIND&#39; refers to transactions used to determine the externally visible addresses...
Definition: stun.c:103
static int stun_id_cmp(stun_trans_id *left, stun_trans_id *right)
Definition: stun.c:251
int errno
if(yyss+yystacksize-1<=yyssp)
Definition: ast_expr2.c:1874
unsigned char ies[0]
Definition: stun.c:77
unsigned short attr
Definition: stun.c:81
static void append_attr_string(struct stun_attr **attr, int attrval, const char *s, int *len, int *left)
append a string to an STUN message
Definition: stun.c:202
#define STUN_BINDERR
Definition: stun.c:105
static int stun_send(int s, struct sockaddr_in *dst, struct stun_header *resp)
wrapper to send an STUN message
Definition: stun.c:235
static char* handle_cli_stun_set_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 470 of file stun.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

471 {
472  switch (cmd) {
473  case CLI_INIT:
474  e->command = "stun set debug {on|off}";
475  e->usage =
476  "Usage: stun set debug {on|off}\n"
477  " Enable/Disable STUN (Simple Traversal of UDP through NATs)\n"
478  " debugging\n";
479  return NULL;
480  case CLI_GENERATE:
481  return NULL;
482  }
483 
484  if (a->argc != e->args)
485  return CLI_SHOWUSAGE;
486 
487  if (!strncasecmp(a->argv[e->args-1], "on", 2))
488  stundebug = 1;
489  else if (!strncasecmp(a->argv[e->args-1], "off", 3))
490  stundebug = 0;
491  else
492  return CLI_SHOWUSAGE;
493 
494  ast_cli(a->fd, "STUN Debugging %s\n", stundebug ? "Enabled" : "Disabled");
495  return CLI_SUCCESS;
496 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
int args
This gets set in ast_cli_register()
Definition: cli.h:179
const int fd
Definition: cli.h:153
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
static int stundebug
Definition: stun.c:43
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static const char* stun_attr2str ( int  msg)
static

helper function to print attribute names

Definition at line 146 of file stun.c.

References STUN_CHANGE_REQUEST, STUN_CHANGED_ADDRESS, STUN_ERROR_CODE, STUN_MAPPED_ADDRESS, STUN_MESSAGE_INTEGRITY, STUN_PASSWORD, STUN_REFLECTED_FROM, STUN_RESPONSE_ADDRESS, STUN_SOURCE_ADDRESS, STUN_UNKNOWN_ATTRIBUTES, and STUN_USERNAME.

Referenced by ast_stun_handle_packet(), and stun_process_attr().

147 {
148  switch (msg) {
149  case STUN_MAPPED_ADDRESS:
150  return "Mapped Address";
152  return "Response Address";
153  case STUN_CHANGE_REQUEST:
154  return "Change Request";
155  case STUN_SOURCE_ADDRESS:
156  return "Source Address";
158  return "Changed Address";
159  case STUN_USERNAME:
160  return "Username";
161  case STUN_PASSWORD:
162  return "Password";
164  return "Message Integrity";
165  case STUN_ERROR_CODE:
166  return "Error Code";
168  return "Unknown Attributes";
169  case STUN_REFLECTED_FROM:
170  return "Reflected From";
171  }
172  return "Non-RFC3489 Attribute";
173 }
#define STUN_PASSWORD
Definition: stun.c:119
#define STUN_MAPPED_ADDRESS
Basic attribute types in stun messages. Messages can also contain custom attributes (codes above 0x7f...
Definition: stun.c:113
#define STUN_CHANGE_REQUEST
Definition: stun.c:115
#define STUN_MESSAGE_INTEGRITY
Definition: stun.c:120
#define STUN_USERNAME
Definition: stun.c:118
#define STUN_CHANGED_ADDRESS
Definition: stun.c:117
#define STUN_REFLECTED_FROM
Definition: stun.c:123
#define STUN_RESPONSE_ADDRESS
Definition: stun.c:114
#define STUN_ERROR_CODE
Definition: stun.c:121
#define STUN_SOURCE_ADDRESS
Definition: stun.c:116
#define STUN_UNKNOWN_ATTRIBUTES
Definition: stun.c:122
static int stun_get_mapped ( struct stun_attr attr,
void *  arg 
)
static

Extract the STUN_MAPPED_ADDRESS from the stun response. This is used as a callback for stun_handle_response when called from ast_stun_request.

Definition at line 361 of file stun.c.

References stun_addr::addr, stun_attr::attr, stun_attr::len, stun_addr::port, and STUN_MAPPED_ADDRESS.

Referenced by ast_stun_request().

362 {
363  struct stun_addr *addr = (struct stun_addr *)(attr + 1);
364  struct sockaddr_in *sa = (struct sockaddr_in *)arg;
365 
366  if (ntohs(attr->attr) != STUN_MAPPED_ADDRESS || ntohs(attr->len) != 8)
367  return 1; /* not us. */
368  sa->sin_port = addr->port;
369  sa->sin_addr.s_addr = addr->addr;
370  return 0;
371 }
#define STUN_MAPPED_ADDRESS
Basic attribute types in stun messages. Messages can also contain custom attributes (codes above 0x7f...
Definition: stun.c:113
unsigned int addr
Definition: stun.c:93
Definition: stun.c:89
unsigned short attr
Definition: stun.c:81
unsigned short len
Definition: stun.c:82
unsigned short port
Definition: stun.c:92
static int stun_id_cmp ( stun_trans_id left,
stun_trans_id right 
)
static

Definition at line 251 of file stun.c.

Referenced by ast_stun_request().

252 {
253  return memcmp(left, right, sizeof(*left));
254 }
static const char* stun_msg2str ( int  msg)
static

helper function to print message names

Definition at line 126 of file stun.c.

References STUN_BINDERR, STUN_BINDREQ, STUN_BINDRESP, STUN_SECERR, STUN_SECREQ, and STUN_SECRESP.

Referenced by ast_stun_handle_packet().

127 {
128  switch (msg) {
129  case STUN_BINDREQ:
130  return "Binding Request";
131  case STUN_BINDRESP:
132  return "Binding Response";
133  case STUN_BINDERR:
134  return "Binding Error Response";
135  case STUN_SECREQ:
136  return "Shared Secret Request";
137  case STUN_SECRESP:
138  return "Shared Secret Response";
139  case STUN_SECERR:
140  return "Shared Secret Error Response";
141  }
142  return "Non-RFC3489 Message";
143 }
#define STUN_BINDRESP
Definition: stun.c:104
#define STUN_BINDREQ
STUN message types &#39;BIND&#39; refers to transactions used to determine the externally visible addresses...
Definition: stun.c:103
#define STUN_SECERR
Definition: stun.c:108
#define STUN_BINDERR
Definition: stun.c:105
#define STUN_SECRESP
Definition: stun.c:107
#define STUN_SECREQ
Definition: stun.c:106
static int stun_process_attr ( struct stun_state state,
struct stun_attr attr 
)
static

Definition at line 181 of file stun.c.

References ast_verbose(), stun_attr::attr, stun_attr::len, stun_state::password, stun_attr2str(), STUN_PASSWORD, STUN_USERNAME, stun_state::username, and stun_attr::value.

Referenced by ast_stun_handle_packet().

182 {
183  if (stundebug)
184  ast_verbose("Found STUN Attribute %s (%04x), length %d\n",
185  stun_attr2str(ntohs(attr->attr)), (unsigned)ntohs(attr->attr), ntohs(attr->len));
186  switch (ntohs(attr->attr)) {
187  case STUN_USERNAME:
188  state->username = (const char *) (attr->value);
189  break;
190  case STUN_PASSWORD:
191  state->password = (const char *) (attr->value);
192  break;
193  default:
194  if (stundebug)
195  ast_verbose("Ignoring STUN attribute %s (%04x), length %d\n",
196  stun_attr2str(ntohs(attr->attr)), (unsigned)ntohs(attr->attr), ntohs(attr->len));
197  }
198  return 0;
199 }
#define STUN_PASSWORD
Definition: stun.c:119
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
const char * username
Definition: stun.c:177
#define STUN_USERNAME
Definition: stun.c:118
const char * password
Definition: stun.c:178
static int stundebug
Definition: stun.c:43
unsigned short attr
Definition: stun.c:81
unsigned short len
Definition: stun.c:82
unsigned char value[0]
Definition: stun.c:83
static const char * stun_attr2str(int msg)
helper function to print attribute names
Definition: stun.c:146
static void stun_req_id ( struct stun_header req)
static

helper function to generate a random request id

Definition at line 257 of file stun.c.

References ast_random(), stun_trans_id::id, and stun_header::id.

Referenced by ast_stun_request().

258 {
259  int x;
260  for (x = 0; x < 4; x++)
261  req->id.id[x] = ast_random();
262 }
unsigned int id[4]
Definition: stun.c:71
long int ast_random(void)
Definition: utils.c:1640
stun_trans_id id
Definition: stun.c:76
static int stun_send ( int  s,
struct sockaddr_in *  dst,
struct stun_header resp 
)
static

wrapper to send an STUN message

Definition at line 235 of file stun.c.

References stun_header::msglen.

Referenced by ast_stun_handle_packet(), and ast_stun_request().

236 {
237  return sendto(s, resp, ntohs(resp->msglen) + sizeof(*resp), 0,
238  (struct sockaddr *)dst, sizeof(*dst));
239 }
unsigned short msglen
Definition: stun.c:75
static void stun_shutdown ( void  )
static

Definition at line 502 of file stun.c.

References ast_cli_unregister_multiple().

Referenced by ast_stun_init().

503 {
504  ast_cli_unregister_multiple(cli_stun, sizeof(cli_stun) / sizeof(struct ast_cli_entry));
505 }
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
descriptor for a cli entry.
Definition: cli.h:165
static struct ast_cli_entry cli_stun[]
Definition: stun.c:498

Variable Documentation

struct ast_cli_entry cli_stun[]
static
Initial value:
= {
AST_CLI_DEFINE(handle_cli_stun_set_debug, "Enable/Disable STUN debugging"),
}
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:191
static char * handle_cli_stun_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: stun.c:470

Definition at line 498 of file stun.c.

int stundebug
static

Are we debugging stun?

Definition at line 43 of file stun.c.