Wed Oct 28 15:48:59 2009

Asterisk developer's documentation


iax2-parser.c File Reference

Implementation of Inter-Asterisk eXchange Protocol, v 2. More...

#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include "asterisk.h"
#include "asterisk/frame.h"
#include "asterisk/utils.h"
#include "asterisk/unaligned.h"
#include "iax2.h"
#include "iax2-parser.h"
#include "iax2-provision.h"

Include dependency graph for iax2-parser.c:

Go to the source code of this file.

Data Structures

struct  iax2_ie

Functions

static void dump_addr (char *output, int maxlen, void *value, int len)
static void dump_byte (char *output, int maxlen, void *value, int len)
static void dump_datetime (char *output, int maxlen, void *value, int len)
static void dump_ies (unsigned char *iedata, int len)
static void dump_int (char *output, int maxlen, void *value, int len)
static void dump_ipaddr (char *output, int maxlen, void *value, int len)
static void dump_prefs (char *output, int maxlen, void *value, int len)
static void dump_prov (char *output, int maxlen, void *value, int len)
static void dump_prov_flags (char *output, int maxlen, void *value, int len)
static void dump_prov_ies (char *output, int maxlen, unsigned char *iedata, int len)
static void dump_samprate (char *output, int maxlen, void *value, int len)
static void dump_short (char *output, int maxlen, void *value, int len)
static void dump_string (char *output, int maxlen, void *value, int len)
void iax_frame_free (struct iax_frame *fr)
struct iax_frameiax_frame_new (int direction, int datalen)
void iax_frame_wrap (struct iax_frame *fr, struct ast_frame *f)
int iax_get_frames (void)
int iax_get_iframes (void)
int iax_get_oframes (void)
const char * iax_ie2str (int ie)
int iax_ie_append (struct iax_ie_data *ied, unsigned char ie)
int iax_ie_append_addr (struct iax_ie_data *ied, unsigned char ie, struct sockaddr_in *sin)
int iax_ie_append_byte (struct iax_ie_data *ied, unsigned char ie, unsigned char dat)
int iax_ie_append_int (struct iax_ie_data *ied, unsigned char ie, unsigned int value)
int iax_ie_append_raw (struct iax_ie_data *ied, unsigned char ie, void *data, int datalen)
int iax_ie_append_short (struct iax_ie_data *ied, unsigned char ie, unsigned short value)
int iax_ie_append_str (struct iax_ie_data *ied, unsigned char ie, char *str)
int iax_parse_ies (struct iax_ies *ies, unsigned char *data, int datalen)
void iax_set_error (void(*func)(const char *))
void iax_set_output (void(*func)(const char *))
void iax_showframe (struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
static void internalerror (const char *str)
static void internaloutput (const char *str)

Variables

static void(* errorf )(const char *str) = internalerror
static int frames = 0
static struct iax2_ie ies []
static int iframes = 0
static int oframes = 0
static void(* outputf )(const char *str) = internaloutput
static struct iax2_ie prov_ies []


Detailed Description

Implementation of Inter-Asterisk eXchange Protocol, v 2.

Definition in file iax2-parser.c.


Function Documentation

static void dump_addr ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 62 of file iax2-parser.c.

References ast_inet_ntoa().

00063 {
00064    struct sockaddr_in sin;
00065    char iabuf[INET_ADDRSTRLEN];
00066    if (len == (int)sizeof(sin)) {
00067       memcpy(&sin, value, len);
00068       snprintf(output, maxlen, "IPV4 %s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
00069    } else {
00070       snprintf(output, maxlen, "Invalid Address");
00071    }
00072 }

static void dump_byte ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 118 of file iax2-parser.c.

00119 {
00120    if (len == (int)sizeof(unsigned char))
00121       snprintf(output, maxlen, "%d", *((unsigned char *)value));
00122    else
00123       ast_copy_string(output, "Invalid BYTE", maxlen);
00124 }

static void dump_datetime ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 126 of file iax2-parser.c.

References get_unaligned_uint32().

00127 {
00128    struct tm tm;
00129    unsigned long val = (unsigned long) ntohl(get_unaligned_uint32(value));
00130    if (len == (int)sizeof(unsigned int)) {
00131       tm.tm_sec  = (val & 0x1f) << 1;
00132       tm.tm_min  = (val >> 5) & 0x3f;
00133       tm.tm_hour = (val >> 11) & 0x1f;
00134       tm.tm_mday = (val >> 16) & 0x1f;
00135       tm.tm_mon  = ((val >> 21) & 0x0f) - 1;
00136       tm.tm_year = ((val >> 25) & 0x7f) + 100;
00137       strftime(output, maxlen, "%Y-%m-%d  %T", &tm); 
00138    } else
00139       ast_copy_string(output, "Invalid DATETIME format!", maxlen);
00140 }

static void dump_ies ( unsigned char *  iedata,
int  len 
) [static]

Definition at line 338 of file iax2-parser.c.

References iax2_ie::dump, iax2_ie::ie, ies, name, and outputf.

Referenced by dundi_showframe(), and iax_showframe().

00339 {
00340    int ielen;
00341    int ie;
00342    int x;
00343    int found;
00344    char interp[1024];
00345    char tmp[1024];
00346    if (len < 2)
00347       return;
00348    while(len > 2) {
00349       ie = iedata[0];
00350       ielen = iedata[1];
00351       if (ielen + 2> len) {
00352          snprintf(tmp, (int)sizeof(tmp), "Total IE length of %d bytes exceeds remaining frame length of %d bytes\n", ielen + 2, len);
00353          outputf(tmp);
00354          return;
00355       }
00356       found = 0;
00357       for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
00358          if (ies[x].ie == ie) {
00359             if (ies[x].dump) {
00360                ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen);
00361                snprintf(tmp, (int)sizeof(tmp), "   %-15.15s : %s\n", ies[x].name, interp);
00362                outputf(tmp);
00363             } else {
00364                if (ielen)
00365                   snprintf(interp, (int)sizeof(interp), "%d bytes", ielen);
00366                else
00367                   strcpy(interp, "Present");
00368                snprintf(tmp, (int)sizeof(tmp), "   %-15.15s : %s\n", ies[x].name, interp);
00369                outputf(tmp);
00370             }
00371             found++;
00372          }
00373       }
00374       if (!found) {
00375          snprintf(tmp, (int)sizeof(tmp), "   Unknown IE %03d  : Present\n", ie);
00376          outputf(tmp);
00377       }
00378       iedata += (2 + ielen);
00379       len -= (2 + ielen);
00380    }
00381    outputf("\n");
00382 }

static void dump_int ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 102 of file iax2-parser.c.

References get_unaligned_uint32().

00103 {
00104    if (len == (int)sizeof(unsigned int))
00105       snprintf(output, maxlen, "%lu", (unsigned long)ntohl(get_unaligned_uint32(value)));
00106    else
00107       ast_copy_string(output, "Invalid INT", maxlen); 
00108 }

static void dump_ipaddr ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 142 of file iax2-parser.c.

References ast_inet_ntoa().

00143 {
00144    struct sockaddr_in sin;
00145    char iabuf[INET_ADDRSTRLEN];
00146    if (len == (int)sizeof(unsigned int)) {
00147       memcpy(&sin.sin_addr, value, len);
00148       ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr);
00149       snprintf(output, maxlen, "%s", iabuf);
00150    } else
00151       ast_copy_string(output, "Invalid IPADDR", maxlen);
00152 }

static void dump_prefs ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 83 of file iax2-parser.c.

References ast_codec_pref_convert(), and ast_codec_pref_string().

00084 {
00085    struct ast_codec_pref pref;
00086    int total_len = 0;
00087 
00088    maxlen--;
00089    total_len = maxlen;
00090 
00091    if (maxlen > len)
00092       maxlen = len;
00093 
00094    strncpy(output, value, maxlen);
00095    output[maxlen] = '\0';
00096    
00097    ast_codec_pref_convert(&pref, output, total_len, 0);
00098    memset(output,0,total_len);
00099    ast_codec_pref_string(&pref, output, total_len);
00100 }

static void dump_prov ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 193 of file iax2-parser.c.

References dump_prov_ies().

00194 {
00195    dump_prov_ies(output, maxlen, value, len);
00196 }

static void dump_prov_flags ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 155 of file iax2-parser.c.

References get_unaligned_uint32(), and iax_provflags2str().

00156 {
00157    char buf[256] = "";
00158    if (len == (int)sizeof(unsigned int))
00159       snprintf(output, maxlen, "%lu (%s)", (unsigned long)ntohl(get_unaligned_uint32(value)),
00160          iax_provflags2str(buf, sizeof(buf), ntohl(get_unaligned_uint32(value))));
00161    else
00162       ast_copy_string(output, "Invalid INT", maxlen);
00163 }

static void dump_prov_ies ( char *  output,
int  maxlen,
unsigned char *  iedata,
int  len 
) [static]

Definition at line 286 of file iax2-parser.c.

References iax2_ie::dump, iax2_ie::ie, and name.

Referenced by dump_prov().

00287 {
00288    int ielen;
00289    int ie;
00290    int x;
00291    int found;
00292    char interp[80];
00293    char tmp[256];
00294    if (len < 2)
00295       return;
00296    strcpy(output, "\n"); 
00297    maxlen -= strlen(output); output += strlen(output);
00298    while(len > 2) {
00299       ie = iedata[0];
00300       ielen = iedata[1];
00301       if (ielen + 2> len) {
00302          snprintf(tmp, (int)sizeof(tmp), "Total Prov IE length of %d bytes exceeds remaining prov frame length of %d bytes\n", ielen + 2, len);
00303          ast_copy_string(output, tmp, maxlen);
00304          maxlen -= strlen(output);
00305          output += strlen(output);
00306          return;
00307       }
00308       found = 0;
00309       for (x=0;x<(int)sizeof(prov_ies) / (int)sizeof(prov_ies[0]); x++) {
00310          if (prov_ies[x].ie == ie) {
00311             if (prov_ies[x].dump) {
00312                prov_ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen);
00313                snprintf(tmp, (int)sizeof(tmp), "       %-15.15s : %s\n", prov_ies[x].name, interp);
00314                ast_copy_string(output, tmp, maxlen);
00315                maxlen -= strlen(output); output += strlen(output);
00316             } else {
00317                if (ielen)
00318                   snprintf(interp, (int)sizeof(interp), "%d bytes", ielen);
00319                else
00320                   strcpy(interp, "Present");
00321                snprintf(tmp, (int)sizeof(tmp), "       %-15.15s : %s\n", prov_ies[x].name, interp);
00322                ast_copy_string(output, tmp, maxlen);
00323                maxlen -= strlen(output); output += strlen(output);
00324             }
00325             found++;
00326          }
00327       }
00328       if (!found) {
00329          snprintf(tmp, (int)sizeof(tmp), "       Unknown Prov IE %03d  : Present\n", ie);
00330          ast_copy_string(output, tmp, maxlen);
00331          maxlen -= strlen(output); output += strlen(output);
00332       }
00333       iedata += (2 + ielen);
00334       len -= (2 + ielen);
00335    }
00336 }

static void dump_samprate ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 165 of file iax2-parser.c.

References IAX_RATE_11KHZ, IAX_RATE_16KHZ, IAX_RATE_22KHZ, IAX_RATE_44KHZ, IAX_RATE_48KHZ, and IAX_RATE_8KHZ.

00166 {
00167    char tmp[256]="";
00168    int sr;
00169    if (len == (int)sizeof(unsigned short)) {
00170       sr = ntohs(*((unsigned short *)value));
00171       if (sr & IAX_RATE_8KHZ)
00172          strcat(tmp, ",8khz");
00173       if (sr & IAX_RATE_11KHZ)
00174          strcat(tmp, ",11.025khz");
00175       if (sr & IAX_RATE_16KHZ)
00176          strcat(tmp, ",16khz");
00177       if (sr & IAX_RATE_22KHZ)
00178          strcat(tmp, ",22.05khz");
00179       if (sr & IAX_RATE_44KHZ)
00180          strcat(tmp, ",44.1khz");
00181       if (sr & IAX_RATE_48KHZ)
00182          strcat(tmp, ",48khz");
00183       if (strlen(tmp))
00184          ast_copy_string(output, &tmp[1], maxlen);
00185       else
00186          ast_copy_string(output, "None Specified!\n", maxlen);
00187    } else
00188       ast_copy_string(output, "Invalid SHORT", maxlen);
00189 
00190 }

static void dump_short ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 110 of file iax2-parser.c.

References get_unaligned_uint16().

00111 {
00112    if (len == (int)sizeof(unsigned short))
00113       snprintf(output, maxlen, "%d", ntohs(get_unaligned_uint16(value)));
00114    else
00115       ast_copy_string(output, "Invalid SHORT", maxlen);
00116 }

static void dump_string ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 74 of file iax2-parser.c.

00075 {
00076    maxlen--;
00077    if (maxlen > len)
00078       maxlen = len;
00079    strncpy(output, value, maxlen);
00080    output[maxlen] = '\0';
00081 }

void iax_frame_free ( struct iax_frame fr  ) 

Definition at line 950 of file iax2-parser.c.

References iax_frame::direction, DIRECTION_INGRESS, DIRECTION_OUTGRESS, errorf, and free.

Referenced by iax2_frame_free(), and network_thread().

00951 {
00952    /* Note: does not remove from scheduler! */
00953    if (fr->direction == DIRECTION_INGRESS)
00954       iframes--;
00955    else if (fr->direction == DIRECTION_OUTGRESS)
00956       oframes--;
00957    else {
00958       errorf("Attempt to double free frame detected\n");
00959       return;
00960    }
00961    fr->direction = 0;
00962    free(fr);
00963    frames--;
00964 }

struct iax_frame* iax_frame_new ( int  direction,
int  datalen 
) [read]

Definition at line 933 of file iax2-parser.c.

References iax_frame::afdatalen, iax_frame::direction, DIRECTION_INGRESS, malloc, and iax_frame::retrans.

Referenced by iax2_send(), and iaxfrdup2().

00934 {
00935    struct iax_frame *fr;
00936    fr = malloc((int)sizeof(struct iax_frame) + datalen);
00937    if (fr) {
00938       fr->afdatalen = datalen;
00939       fr->direction = direction;
00940       fr->retrans = -1;
00941       frames++;
00942       if (fr->direction == DIRECTION_INGRESS)
00943          iframes++;
00944       else
00945          oframes++;
00946    }
00947    return fr;
00948 }

void iax_frame_wrap ( struct iax_frame fr,
struct ast_frame f 
)

Definition at line 903 of file iax2-parser.c.

References iax_frame::af, iax_frame::afdata, iax_frame::afdatalen, AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_swapcopy_samples(), ast_frame::data, ast_frame::datalen, ast_frame::delivery, ast_frame::frametype, LOG_ERROR, ast_frame::mallocd, ast_frame::offset, ast_frame::samples, ast_frame::src, and ast_frame::subclass.

Referenced by iax2_send(), iaxfrdup2(), and socket_read().

00904 {
00905    fr->af.frametype = f->frametype;
00906    fr->af.subclass = f->subclass;
00907    fr->af.mallocd = 0;           /* Our frame is static relative to the container */
00908    fr->af.datalen = f->datalen;
00909    fr->af.samples = f->samples;
00910    fr->af.offset = AST_FRIENDLY_OFFSET;
00911    fr->af.src = f->src;
00912    fr->af.delivery.tv_sec = 0;
00913    fr->af.delivery.tv_usec = 0;
00914    fr->af.data = fr->afdata;
00915    if (fr->af.datalen) {
00916       size_t copy_len = fr->af.datalen;
00917       if (copy_len > fr->afdatalen) {
00918          ast_log(LOG_ERROR, "Losing frame data because destination buffer size '%d' bytes not big enough for '%d' bytes in the frame\n",
00919             (int) fr->afdatalen, (int) fr->af.datalen);
00920          copy_len = fr->afdatalen;
00921       }
00922 #if __BYTE_ORDER == __LITTLE_ENDIAN
00923       /* We need to byte-swap slinear samples from network byte order */
00924       if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass == AST_FORMAT_SLINEAR)) {
00925          /* 2 bytes / sample for SLINEAR */
00926          ast_swapcopy_samples(fr->af.data, f->data, copy_len / 2);
00927       } else
00928 #endif
00929          memcpy(fr->af.data, f->data, copy_len);
00930    }
00931 }

int iax_get_frames ( void   ) 

Definition at line 966 of file iax2-parser.c.

Referenced by iax2_show_stats().

00966 { return frames; }

int iax_get_iframes ( void   ) 

Definition at line 967 of file iax2-parser.c.

Referenced by iax2_show_stats().

00967 { return iframes; }

int iax_get_oframes ( void   ) 

Definition at line 968 of file iax2-parser.c.

Referenced by iax2_show_stats().

00968 { return oframes; }

const char* iax_ie2str ( int  ie  ) 

Definition at line 275 of file iax2-parser.c.

References ies, and iax2_ie::name.

Referenced by iax_ie_append_raw(), and iax_parse_ies().

00276 {
00277    int x;
00278    for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
00279       if (ies[x].ie == ie)
00280          return ies[x].name;
00281    }
00282    return "Unknown IE";
00283 }

int iax_ie_append ( struct iax_ie_data ied,
unsigned char  ie 
)

Definition at line 574 of file iax2-parser.c.

References iax_ie_append_raw().

Referenced by iax2_call(), and iax_firmware_append().

00575 {
00576    return iax_ie_append_raw(ied, ie, NULL, 0);
00577 }

int iax_ie_append_addr ( struct iax_ie_data ied,
unsigned char  ie,
struct sockaddr_in *  sin 
)

Definition at line 545 of file iax2-parser.c.

References iax_ie_append_raw().

Referenced by iax2_start_transfer(), and update_registry().

00546 {
00547    return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in));
00548 }

int iax_ie_append_byte ( struct iax_ie_data ied,
unsigned char  ie,
unsigned char  dat 
)

Definition at line 569 of file iax2-parser.c.

References iax_ie_append_raw().

Referenced by auth_reject(), authenticate_request(), auto_hangup(), iax2_call(), iax2_hangup(), iax_provision_build(), and socket_read().

00570 {
00571    return iax_ie_append_raw(ied, ie, &dat, 1);
00572 }

int iax_ie_append_int ( struct iax_ie_data ied,
unsigned char  ie,
unsigned int  value 
)

Definition at line 550 of file iax2-parser.c.

References iax_ie_append_raw().

Referenced by cache_get_callno_locked(), construct_rr(), iax2_call(), iax2_start_transfer(), iax_firmware_append(), iax_provision_build(), socket_read(), try_transfer(), and update_registry().

00551 {
00552    unsigned int newval;
00553    newval = htonl(value);
00554    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00555 }

int iax_ie_append_raw ( struct iax_ie_data ied,
unsigned char  ie,
void *  data,
int  datalen 
)

Definition at line 530 of file iax2-parser.c.

References iax_ie_data::buf, errorf, iax_ie2str(), and iax_ie_data::pos.

Referenced by iax2_provision(), iax_firmware_append(), iax_ie_append(), iax_ie_append_addr(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), and iax_ie_append_str().

00531 {
00532    char tmp[256];
00533    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00534       snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", iax_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
00535       errorf(tmp);
00536       return -1;
00537    }
00538    ied->buf[ied->pos++] = ie;
00539    ied->buf[ied->pos++] = datalen;
00540    memcpy(ied->buf + ied->pos, data, datalen);
00541    ied->pos += datalen;
00542    return 0;
00543 }

int iax_ie_append_short ( struct iax_ie_data ied,
unsigned char  ie,
unsigned short  value 
)

Definition at line 557 of file iax2-parser.c.

References iax_ie_append_raw().

Referenced by authenticate_request(), cache_get_callno_locked(), construct_rr(), dp_lookup(), iax2_call(), iax2_do_register(), iax2_start_transfer(), iax_provision_build(), registry_authrequest(), registry_rerequest(), socket_read(), and update_registry().

00558 {
00559    unsigned short newval;
00560    newval = htons(value);
00561    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00562 }

int iax_ie_append_str ( struct iax_ie_data ied,
unsigned char  ie,
char *  str 
)

int iax_parse_ies ( struct iax_ies ies,
unsigned char *  data,
int  datalen 
)

Definition at line 589 of file iax2-parser.c.

References iax_ies::adsicpe, iax_ies::apparent_addr, iax_ies::authmethods, iax_ies::autoanswer, iax_ies::called_context, iax_ies::called_number, iax_ies::calling_ani, iax_ies::calling_name, iax_ies::calling_number, iax_ies::calling_pres, iax_ies::calling_tns, iax_ies::calling_ton, iax_ies::callno, iax_ies::calltoken, iax_ies::calltokendata, iax_ies::capability, iax_ies::cause, iax_ies::causecode, iax_ies::challenge, iax_ies::codec_prefs, iax_ies::datetime, iax_ies::devicetype, iax_ies::dnid, iax_ies::dpstatus, iax_ies::enckey, iax_ies::enckeylen, iax_ies::encmethods, errorf, iax_ies::firmwarever, iax_ies::format, iax_ies::fwdata, iax_ies::fwdatalen, iax_ies::fwdesc, get_unaligned_uint16(), get_unaligned_uint32(), iax_ie2str(), IAX_IE_ADSICPE, IAX_IE_APPARENT_ADDR, IAX_IE_AUTHMETHODS, IAX_IE_AUTOANSWER, IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CALLING_ANI, IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_CALLINGPRES, IAX_IE_CALLINGTNS, IAX_IE_CALLINGTON, IAX_IE_CALLNO, IAX_IE_CALLTOKEN, IAX_IE_CAPABILITY, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_CHALLENGE, IAX_IE_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DEVICETYPE, IAX_IE_DNID, IAX_IE_DPSTATUS, IAX_IE_ENCKEY, IAX_IE_ENCRYPTION, IAX_IE_FIRMWAREVER, IAX_IE_FORMAT, IAX_IE_FWBLOCKDATA, IAX_IE_FWBLOCKDESC, IAX_IE_IAX_UNKNOWN, IAX_IE_LANGUAGE, IAX_IE_MD5_RESULT, IAX_IE_MSGCOUNT, IAX_IE_MUSICONHOLD, IAX_IE_PASSWORD, IAX_IE_PROVVER, IAX_IE_RDNIS, IAX_IE_REFRESH, IAX_IE_RR_DELAY, IAX_IE_RR_DROPPED, IAX_IE_RR_JITTER, IAX_IE_RR_LOSS, IAX_IE_RR_OOO, IAX_IE_RR_PKTS, IAX_IE_RSA_RESULT, IAX_IE_SAMPLINGRATE, IAX_IE_SERVICEIDENT, IAX_IE_TRANSFERID, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_RATE_8KHZ, iax_ies::iax_unknown, iax_ies::language, iax_ies::md5_result, iax_ies::msgcount, iax_ies::musiconhold, outputf, iax_ies::password, iax_ies::provver, iax_ies::provverpres, iax_ies::rdnis, iax_ies::refresh, iax_ies::rr_delay, iax_ies::rr_dropped, iax_ies::rr_jitter, iax_ies::rr_loss, iax_ies::rr_ooo, iax_ies::rr_pkts, iax_ies::rsa_result, iax_ies::samprate, iax_ies::serviceident, iax_ies::transferid, iax_ies::username, and iax_ies::version.

Referenced by socket_read().

00590 {
00591    /* Parse data into information elements */
00592    int len;
00593    int ie;
00594    char tmp[256];
00595    memset(ies, 0, (int)sizeof(struct iax_ies));
00596    ies->msgcount = -1;
00597    ies->firmwarever = -1;
00598    ies->calling_ton = -1;
00599    ies->calling_tns = -1;
00600    ies->calling_pres = -1;
00601    ies->samprate = IAX_RATE_8KHZ;
00602    while(datalen >= 2) {
00603       ie = data[0];
00604       len = data[1];
00605       if (len > datalen - 2) {
00606          errorf("Information element length exceeds message size\n");
00607          return -1;
00608       }
00609       switch(ie) {
00610       case IAX_IE_CALLED_NUMBER:
00611          ies->called_number = (char *)data + 2;
00612          break;
00613       case IAX_IE_CALLING_NUMBER:
00614          ies->calling_number = (char *)data + 2;
00615          break;
00616       case IAX_IE_CALLING_ANI:
00617          ies->calling_ani = (char *)data + 2;
00618          break;
00619       case IAX_IE_CALLING_NAME:
00620          ies->calling_name = (char *)data + 2;
00621          break;
00622       case IAX_IE_CALLED_CONTEXT:
00623          ies->called_context = (char *)data + 2;
00624          break;
00625       case IAX_IE_USERNAME:
00626          ies->username = (char *)data + 2;
00627          break;
00628       case IAX_IE_PASSWORD:
00629          ies->password = (char *)data + 2;
00630          break;
00631       case IAX_IE_CODEC_PREFS:
00632          ies->codec_prefs = (char *)data + 2;
00633          break;
00634       case IAX_IE_CAPABILITY:
00635          if (len != (int)sizeof(unsigned int)) {
00636             snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00637             errorf(tmp);
00638          } else
00639             ies->capability = ntohl(get_unaligned_uint32(data + 2));
00640          break;
00641       case IAX_IE_FORMAT:
00642          if (len != (int)sizeof(unsigned int)) {
00643             snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00644             errorf(tmp);
00645          } else
00646             ies->format = ntohl(get_unaligned_uint32(data + 2));
00647          break;
00648       case IAX_IE_LANGUAGE:
00649          ies->language = (char *)data + 2;
00650          break;
00651       case IAX_IE_VERSION:
00652          if (len != (int)sizeof(unsigned short)) {
00653             snprintf(tmp, (int)sizeof(tmp),  "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00654             errorf(tmp);
00655          } else
00656             ies->version = ntohs(get_unaligned_uint16(data + 2));
00657          break;
00658       case IAX_IE_ADSICPE:
00659          if (len != (int)sizeof(unsigned short)) {
00660             snprintf(tmp, (int)sizeof(tmp), "Expecting adsicpe to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00661             errorf(tmp);
00662          } else
00663             ies->adsicpe = ntohs(get_unaligned_uint16(data + 2));
00664          break;
00665       case IAX_IE_SAMPLINGRATE:
00666          if (len != (int)sizeof(unsigned short)) {
00667             snprintf(tmp, (int)sizeof(tmp), "Expecting samplingrate to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00668             errorf(tmp);
00669          } else
00670             ies->samprate = ntohs(get_unaligned_uint16(data + 2));
00671          break;
00672       case IAX_IE_DNID:
00673          ies->dnid = (char *)data + 2;
00674          break;
00675       case IAX_IE_RDNIS:
00676          ies->rdnis = (char *)data + 2;
00677          break;
00678       case IAX_IE_AUTHMETHODS:
00679          if (len != (int)sizeof(unsigned short))  {
00680             snprintf(tmp, (int)sizeof(tmp), "Expecting authmethods to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00681             errorf(tmp);
00682          } else
00683             ies->authmethods = ntohs(get_unaligned_uint16(data + 2));
00684          break;
00685       case IAX_IE_ENCRYPTION:
00686          if (len != (int)sizeof(unsigned short))  {
00687             snprintf(tmp, (int)sizeof(tmp), "Expecting encryption to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00688             errorf(tmp);
00689          } else
00690             ies->encmethods = ntohs(get_unaligned_uint16(data + 2));
00691          break;
00692       case IAX_IE_CHALLENGE:
00693          ies->challenge = (char *)data + 2;
00694          break;
00695       case IAX_IE_MD5_RESULT:
00696          ies->md5_result = (char *)data + 2;
00697          break;
00698       case IAX_IE_RSA_RESULT:
00699          ies->rsa_result = (char *)data + 2;
00700          break;
00701       case IAX_IE_APPARENT_ADDR:
00702          ies->apparent_addr = ((struct sockaddr_in *)(data + 2));
00703          break;
00704       case IAX_IE_REFRESH:
00705          if (len != (int)sizeof(unsigned short)) {
00706             snprintf(tmp, (int)sizeof(tmp),  "Expecting refresh to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00707             errorf(tmp);
00708          } else
00709             ies->refresh = ntohs(get_unaligned_uint16(data + 2));
00710          break;
00711       case IAX_IE_DPSTATUS:
00712          if (len != (int)sizeof(unsigned short)) {
00713             snprintf(tmp, (int)sizeof(tmp),  "Expecting dpstatus to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00714             errorf(tmp);
00715          } else
00716             ies->dpstatus = ntohs(get_unaligned_uint16(data + 2));
00717          break;
00718       case IAX_IE_CALLNO:
00719          if (len != (int)sizeof(unsigned short)) {
00720             snprintf(tmp, (int)sizeof(tmp),  "Expecting callno to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00721             errorf(tmp);
00722          } else
00723             ies->callno = ntohs(get_unaligned_uint16(data + 2));
00724          break;
00725       case IAX_IE_CAUSE:
00726          ies->cause = (char *)data + 2;
00727          break;
00728       case IAX_IE_CAUSECODE:
00729          if (len != 1) {
00730             snprintf(tmp, (int)sizeof(tmp), "Expecting causecode to be single byte but was %d\n", len);
00731             errorf(tmp);
00732          } else {
00733             ies->causecode = data[2];
00734          }
00735          break;
00736       case IAX_IE_IAX_UNKNOWN:
00737          if (len == 1)
00738             ies->iax_unknown = data[2];
00739          else {
00740             snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len);
00741             errorf(tmp);
00742          }
00743          break;
00744       case IAX_IE_MSGCOUNT:
00745          if (len != (int)sizeof(unsigned short)) {
00746             snprintf(tmp, (int)sizeof(tmp), "Expecting msgcount to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00747             errorf(tmp);
00748          } else
00749             ies->msgcount = ntohs(get_unaligned_uint16(data + 2));   
00750          break;
00751       case IAX_IE_AUTOANSWER:
00752          ies->autoanswer = 1;
00753          break;
00754       case IAX_IE_MUSICONHOLD:
00755          ies->musiconhold = 1;
00756          break;
00757       case IAX_IE_TRANSFERID:
00758          if (len != (int)sizeof(unsigned int)) {
00759             snprintf(tmp, (int)sizeof(tmp), "Expecting transferid to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00760             errorf(tmp);
00761          } else
00762             ies->transferid = ntohl(get_unaligned_uint32(data + 2));
00763          break;
00764       case IAX_IE_DATETIME:
00765          if (len != (int)sizeof(unsigned int)) {
00766             snprintf(tmp, (int)sizeof(tmp), "Expecting date/time to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00767             errorf(tmp);
00768          } else
00769             ies->datetime = ntohl(get_unaligned_uint32(data + 2));
00770          break;
00771       case IAX_IE_FIRMWAREVER:
00772          if (len != (int)sizeof(unsigned short)) {
00773             snprintf(tmp, (int)sizeof(tmp), "Expecting firmwarever to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00774             errorf(tmp);
00775          } else
00776             ies->firmwarever = ntohs(get_unaligned_uint16(data + 2));   
00777          break;
00778       case IAX_IE_DEVICETYPE:
00779          ies->devicetype = (char *)data + 2;
00780          break;
00781       case IAX_IE_SERVICEIDENT:
00782          ies->serviceident = (char *)data + 2;
00783          break;
00784       case IAX_IE_FWBLOCKDESC:
00785          if (len != (int)sizeof(unsigned int)) {
00786             snprintf(tmp, (int)sizeof(tmp), "Expected block desc to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00787             errorf(tmp);
00788          } else
00789             ies->fwdesc = ntohl(get_unaligned_uint32(data + 2));
00790          break;
00791       case IAX_IE_FWBLOCKDATA:
00792          ies->fwdata = data + 2;
00793          ies->fwdatalen = len;
00794          break;
00795       case IAX_IE_ENCKEY:
00796          ies->enckey = data + 2;
00797          ies->enckeylen = len;
00798          break;
00799       case IAX_IE_PROVVER:
00800          if (len != (int)sizeof(unsigned int)) {
00801             snprintf(tmp, (int)sizeof(tmp), "Expected provisioning version to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00802             errorf(tmp);
00803          } else {
00804             ies->provverpres = 1;
00805             ies->provver = ntohl(get_unaligned_uint32(data + 2));
00806          }
00807          break;
00808       case IAX_IE_CALLINGPRES:
00809          if (len == 1)
00810             ies->calling_pres = data[2];
00811          else {
00812             snprintf(tmp, (int)sizeof(tmp), "Expected single byte callingpres, but was %d long\n", len);
00813             errorf(tmp);
00814          }
00815          break;
00816       case IAX_IE_CALLINGTON:
00817          if (len == 1)
00818             ies->calling_ton = data[2];
00819          else {
00820             snprintf(tmp, (int)sizeof(tmp), "Expected single byte callington, but was %d long\n", len);
00821             errorf(tmp);
00822          }
00823          break;
00824       case IAX_IE_CALLINGTNS:
00825          if (len != (int)sizeof(unsigned short)) {
00826             snprintf(tmp, (int)sizeof(tmp), "Expecting callingtns to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00827             errorf(tmp);
00828          } else
00829             ies->calling_tns = ntohs(get_unaligned_uint16(data + 2));   
00830          break;
00831                case IAX_IE_RR_JITTER:
00832                        if (len != (int)sizeof(unsigned int)) {
00833                                snprintf(tmp, (int)sizeof(tmp), "Expected jitter rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00834                                errorf(tmp);
00835                        } else {
00836                                ies->rr_jitter = ntohl(get_unaligned_uint32(data + 2));
00837                        }
00838                        break;
00839                case IAX_IE_RR_LOSS:
00840                        if (len != (int)sizeof(unsigned int)) {
00841                                snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00842                                errorf(tmp);
00843                        } else {
00844                                ies->rr_loss = ntohl(get_unaligned_uint32(data + 2));
00845                        }
00846                        break;
00847                case IAX_IE_RR_PKTS:
00848                        if (len != (int)sizeof(unsigned int)) {
00849                                snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00850                                errorf(tmp);
00851                        } else {
00852                                ies->rr_pkts = ntohl(get_unaligned_uint32(data + 2));
00853                        }
00854                        break;
00855                case IAX_IE_RR_DELAY:
00856                        if (len != (int)sizeof(unsigned short)) {
00857                                snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00858                         errorf(tmp);
00859                        } else {
00860                                ies->rr_delay = ntohs(get_unaligned_uint16(data + 2));
00861                        }
00862                        break;
00863       case IAX_IE_RR_DROPPED:
00864          if (len != (int)sizeof(unsigned int)) {
00865             snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00866             errorf(tmp);
00867          } else {
00868             ies->rr_dropped = ntohl(get_unaligned_uint32(data + 2));
00869          }
00870          break;
00871       case IAX_IE_RR_OOO:
00872          if (len != (int)sizeof(unsigned int)) {
00873             snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00874             errorf(tmp);
00875          } else {
00876             ies->rr_ooo = ntohl(get_unaligned_uint32(data + 2));
00877          }
00878          break;
00879       case IAX_IE_CALLTOKEN:
00880          if (len) {
00881             ies->calltokendata = (unsigned char *) data + 2;
00882          }
00883          ies->calltoken = 1;
00884          break;
00885       default:
00886          snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len);
00887          outputf(tmp);
00888       }
00889       /* Overwrite information element with 0, to null terminate previous portion */
00890       data[0] = 0;
00891       datalen -= (len + 2);
00892       data += (len + 2);
00893    }
00894    /* Null-terminate last field */
00895    *data = '\0';
00896    if (datalen) {
00897       errorf("Invalid information element contents, strange boundary\n");
00898       return -1;
00899    }
00900    return 0;
00901 }

void iax_set_error ( void(*)(const char *)  func  ) 

Definition at line 584 of file iax2-parser.c.

References errorf.

Referenced by load_module().

00585 {
00586    errorf = func;
00587 }

void iax_set_output ( void(*)(const char *)  func  ) 

Definition at line 579 of file iax2-parser.c.

References outputf.

Referenced by load_module().

00580 {
00581    outputf = func;
00582 }

void iax_showframe ( struct iax_frame f,
struct ast_iax2_full_hdr fhi,
int  rx,
struct sockaddr_in *  sin,
int  datalen 
)

Definition at line 384 of file iax2-parser.c.

References AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_IAX, ast_inet_ntoa(), ast_iax2_full_hdr::csub, iax_frame::data, ast_iax2_full_hdr::dcallno, dump_ies(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iedata, ast_iax2_full_hdr::iseqno, ast_iax2_full_hdr::oseqno, outputf, iax_frame::retries, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::ts, and ast_iax2_full_hdr::type.

Referenced by iax2_send(), raw_hangup(), send_packet(), and socket_read().

00385 {
00386    const char *frames[] = {
00387       "(0?)",
00388       "DTMF   ",
00389       "VOICE  ",
00390       "VIDEO  ",
00391       "CONTROL",
00392       "NULL   ",
00393       "IAX    ",
00394       "TEXT   ",
00395       "IMAGE  ",
00396       "HTML   ",
00397       "CNG    " };
00398    const char *iaxs[] = {
00399       "(0?)",
00400       "NEW    ",
00401       "PING   ",
00402       "PONG   ",
00403       "ACK    ",
00404       "HANGUP ",
00405       "REJECT ",
00406       "ACCEPT ",
00407       "AUTHREQ",
00408       "AUTHREP",
00409       "INVAL  ",
00410       "LAGRQ  ",
00411       "LAGRP  ",
00412       "REGREQ ",
00413       "REGAUTH",
00414       "REGACK ",
00415       "REGREJ ",
00416       "REGREL ",
00417       "VNAK   ",
00418       "DPREQ  ",
00419       "DPREP  ",
00420       "DIAL   ",
00421       "TXREQ  ",
00422       "TXCNT  ",
00423       "TXACC  ",
00424       "TXREADY",
00425       "TXREL  ",
00426       "TXREJ  ",
00427       "QUELCH ",
00428       "UNQULCH",
00429       "POKE   ",
00430       "PAGE   ",
00431       "MWI    ",
00432       "UNSPRTD",
00433       "TRANSFR",
00434       "PROVISN",
00435       "FWDWNLD",
00436       "FWDATA ",
00437       "TXMEDIA",
00438       "RTKEY  ",
00439       "CTOKEN ",
00440    };
00441    const char *cmds[] = {
00442       "(0?)",
00443       "HANGUP ",
00444       "RING   ",
00445       "RINGING",
00446       "ANSWER ",
00447       "BUSY   ",
00448       "TKOFFHK",
00449       "OFFHOOK" };
00450    struct ast_iax2_full_hdr *fh;
00451    char retries[20];
00452    char class2[20];
00453    char subclass2[20];
00454    const char *class;
00455    const char *subclass;
00456    char *dir;
00457    char tmp[512];
00458    char iabuf[INET_ADDRSTRLEN];
00459 
00460    switch(rx) {
00461    case 0:
00462       dir = "Tx";
00463       break;
00464    case 2:
00465       dir = "TE";
00466       break;
00467    case 3:
00468       dir = "RD";
00469       break;
00470    default:
00471       dir = "Rx";
00472       break;
00473    }
00474    if (f) {
00475       fh = f->data;
00476       snprintf(retries, sizeof(retries), "%03d", f->retries);
00477    } else {
00478       fh = fhi;
00479       if (ntohs(fh->dcallno) & IAX_FLAG_RETRANS)
00480          strcpy(retries, "Yes");
00481       else
00482          strcpy(retries, " No");
00483    }
00484    if (!(ntohs(fh->scallno) & IAX_FLAG_FULL)) {
00485       /* Don't mess with mini-frames */
00486       return;
00487    }
00488    if (fh->type >= (int)sizeof(frames)/(int)sizeof(frames[0])) {
00489       snprintf(class2, sizeof(class2), "(%d?)", fh->type);
00490       class = class2;
00491    } else {
00492       class = frames[(int)fh->type];
00493    }
00494    if (fh->type == AST_FRAME_DTMF) {
00495       sprintf(subclass2, "%c", fh->csub);
00496       subclass = subclass2;
00497    } else if (fh->type == AST_FRAME_IAX) {
00498       if (fh->csub >= (int)sizeof(iaxs)/(int)sizeof(iaxs[0])) {
00499          snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub);
00500          subclass = subclass2;
00501       } else {
00502          subclass = iaxs[(int)fh->csub];
00503       }
00504    } else if (fh->type == AST_FRAME_CONTROL) {
00505       if (fh->csub >= (int)sizeof(cmds)/(int)sizeof(cmds[0])) {
00506          snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub);
00507          subclass = subclass2;
00508       } else {
00509          subclass = cmds[(int)fh->csub];
00510       }
00511    } else {
00512       snprintf(subclass2, sizeof(subclass2), "%d", fh->csub);
00513       subclass = subclass2;
00514    }
00515    snprintf(tmp, sizeof(tmp), 
00516        "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s Subclass: %s\n",
00517        dir,
00518        retries, fh->oseqno, fh->iseqno, class, subclass);
00519    outputf(tmp);
00520    snprintf(tmp, sizeof(tmp), 
00521        "   Timestamp: %05lums  SCall: %5.5d  DCall: %5.5d [%s:%d]\n",
00522        (unsigned long)ntohl(fh->ts),
00523        ntohs(fh->scallno) & ~IAX_FLAG_FULL, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS,
00524        ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port));
00525    outputf(tmp);
00526    if (fh->type == AST_FRAME_IAX)
00527       dump_ies(fh->iedata, datalen);
00528 }

static void internalerror ( const char *  str  )  [static]

Definition at line 54 of file iax2-parser.c.

00055 {
00056    fprintf(stderr, "WARNING: %s", str);
00057 }

static void internaloutput ( const char *  str  )  [static]

Definition at line 49 of file iax2-parser.c.

00050 {
00051    fputs(str, stdout);
00052 }


Variable Documentation

void(* errorf)(const char *str) = internalerror [static]

int frames = 0 [static]

Definition at line 45 of file iax2-parser.c.

Referenced by queue_put().

struct iax2_ie ies[] [static]

Referenced by dump_ies(), dundi_ie2str(), and iax_ie2str().

int iframes = 0 [static]

Definition at line 46 of file iax2-parser.c.

int oframes = 0 [static]

Definition at line 47 of file iax2-parser.c.

void(* outputf)(const char *str) = internaloutput [static]

struct iax2_ie prov_ies[] [static]

Definition at line 255 of file iax2-parser.c.


Generated on Wed Oct 28 15:48:59 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6