Mon Mar 19 11:30:48 2012

Asterisk developer's documentation


iax2-parser.h File Reference

Implementation of the IAX2 protocol. More...

#include "asterisk/linkedlists.h"
#include "asterisk/crypto.h"
#include "asterisk/frame_defs.h"

Go to the source code of this file.

Data Structures

struct  iax_frame
struct  iax_ie_data
struct  iax_ies

Defines

#define DIRECTION_INGRESS   1
#define DIRECTION_OUTGRESS   2

Functions

void iax_frame_free (struct iax_frame *fr)
iax_frameiax_frame_new (int direction, int datalen, unsigned int cacheable)
void iax_frame_subclass2str (enum iax_frame_subclass subclass, char *str, size_t len)
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, const 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, const 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, const char *str)
int iax_ie_append_versioned_uint64 (struct iax_ie_data *ied, unsigned char ie, unsigned char version, uint64_t value)
int iax_parse_ies (struct iax_ies *ies, unsigned char *data, int datalen)
void iax_set_error (void(*output)(const char *data))
void iax_set_output (void(*output)(const char *data))
void iax_showframe (struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)


Detailed Description

Implementation of the IAX2 protocol.

Definition in file iax2-parser.h.


Define Documentation

#define DIRECTION_INGRESS   1

Definition at line 85 of file iax2-parser.h.

Referenced by iax_frame_free(), iax_frame_new(), and iaxfrdup2().

#define DIRECTION_OUTGRESS   2

Definition at line 86 of file iax2-parser.h.

Referenced by iax2_send(), iax_frame_free(), and send_trunk().


Function Documentation

void iax_frame_free ( struct iax_frame fr  ) 

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

References iax_frame::afdatalen, ast_atomic_fetchadd_int(), ast_free, AST_LIST_FIRST, AST_LIST_INSERT_HEAD, AST_LIST_INSERT_TAIL, ast_threadstorage_get(), iax_frame::cacheable, iax_frame::direction, DIRECTION_INGRESS, DIRECTION_OUTGRESS, errorf, frame_cache, FRAME_CACHE_MAX_SIZE, and iax_frames::list.

Referenced by iax2_frame_free(), and transmit_frame().

01228 {
01229 #if !defined(LOW_MEMORY)
01230    struct iax_frames *iax_frames = NULL;
01231 #endif
01232 
01233    /* Note: does not remove from scheduler! */
01234    if (fr->direction == DIRECTION_INGRESS)
01235       ast_atomic_fetchadd_int(&iframes, -1);
01236    else if (fr->direction == DIRECTION_OUTGRESS)
01237       ast_atomic_fetchadd_int(&oframes, -1);
01238    else {
01239       errorf("Attempt to double free frame detected\n");
01240       return;
01241    }
01242    ast_atomic_fetchadd_int(&frames, -1);
01243 
01244 #if !defined(LOW_MEMORY)
01245    if (!fr->cacheable || !(iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
01246       ast_free(fr);
01247       return;
01248    }
01249 
01250    if (iax_frames->size < FRAME_CACHE_MAX_SIZE) {
01251       fr->direction = 0;
01252       /* Pseudo-sort: keep smaller frames at the top of the list. This should
01253        * increase the chance that we pick the smallest applicable frame for use. */
01254       if (AST_LIST_FIRST(&iax_frames->list) && AST_LIST_FIRST(&iax_frames->list)->afdatalen < fr->afdatalen) {
01255          AST_LIST_INSERT_TAIL(&iax_frames->list, fr, list);
01256       } else {
01257          AST_LIST_INSERT_HEAD(&iax_frames->list, fr, list);
01258       }
01259       iax_frames->size++;
01260       return;
01261    }
01262 #endif
01263    ast_free(fr);
01264 }

struct iax_frame* iax_frame_new ( int  direction,
int  datalen,
unsigned int  cacheable 
)

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

References iax_frame::afdatalen, ast_atomic_fetchadd_int(), ast_calloc, ast_calloc_cache, AST_LIST_FIRST, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_realloc, ast_threadstorage_get(), DIRECTION_INGRESS, frame_cache, FRAME_CACHE_MAX_SIZE, and iax_frame::list.

Referenced by iax2_send(), and iaxfrdup2().

01170 {
01171    struct iax_frame *fr = NULL;
01172 
01173 #if !defined(LOW_MEMORY)
01174    struct iax_frames *iax_frames = NULL;
01175    struct iax_frame *smallest = NULL;
01176 
01177    /* Attempt to get a frame from this thread's cache */
01178    if ((iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
01179       smallest = AST_LIST_FIRST(&iax_frames->list);
01180       AST_LIST_TRAVERSE_SAFE_BEGIN(&iax_frames->list, fr, list) {
01181          if (fr->afdatalen >= datalen) {
01182             size_t afdatalen = fr->afdatalen;
01183             AST_LIST_REMOVE_CURRENT(list);
01184             iax_frames->size--;
01185             memset(fr, 0, sizeof(*fr));
01186             fr->afdatalen = afdatalen;
01187             break;
01188          } else if (smallest->afdatalen > fr->afdatalen) {
01189             smallest = fr;
01190          }
01191       }
01192       AST_LIST_TRAVERSE_SAFE_END;
01193    }
01194    if (!fr) {
01195       if (iax_frames->size >= FRAME_CACHE_MAX_SIZE && smallest) {
01196          /* Make useless cache into something more useful */
01197          AST_LIST_REMOVE(&iax_frames->list, smallest, list);
01198          if (!(fr = ast_realloc(smallest, sizeof(*fr) + datalen))) {
01199             AST_LIST_INSERT_TAIL(&iax_frames->list, smallest, list);
01200             return NULL;
01201          }
01202       } else if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen)))
01203          return NULL;
01204       fr->afdatalen = datalen;
01205    }
01206 #else
01207    if (!(fr = ast_calloc(1, sizeof(*fr) + datalen)))
01208       return NULL;
01209    fr->afdatalen = datalen;
01210 #endif
01211 
01212 
01213    fr->direction = direction;
01214    fr->retrans = -1;
01215    fr->cacheable = cacheable;
01216    
01217    if (fr->direction == DIRECTION_INGRESS)
01218       ast_atomic_fetchadd_int(&iframes, 1);
01219    else
01220       ast_atomic_fetchadd_int(&oframes, 1);
01221    
01222    ast_atomic_fetchadd_int(&frames, 1);
01223 
01224    return fr;
01225 }

void iax_frame_subclass2str ( enum iax_frame_subclass  subclass,
char *  str,
size_t  len 
)

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

References ast_copy_string(), IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_CALLTOKEN, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_MWI, IAX_COMMAND_NEW, IAX_COMMAND_PAGE, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_PROVISION, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_RTKEY, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, and IAX_COMMAND_VNAK.

Referenced by ast_cli_netstats(), handle_cli_iax2_show_channels(), and iax_showframe().

00430 {
00431    const char *cmd = "Unknown";
00432 
00433    /* if an error occurs here during compile, that means a new iax frame subclass
00434     * has been added to the iax_frame_subclass enum.  Add the new subclass to the
00435     * switch case and make sure to update it with a new string representation. */
00436    switch (subclass) {
00437    case IAX_COMMAND_NEW:
00438       cmd = "NEW    ";
00439       break;
00440    case IAX_COMMAND_PING:
00441       cmd = "PING   ";
00442       break;
00443    case IAX_COMMAND_PONG:
00444       cmd = "PONG   ";
00445       break;
00446    case IAX_COMMAND_ACK:
00447       cmd = "ACK    ";
00448       break;
00449    case IAX_COMMAND_HANGUP:
00450       cmd = "HANGUP ";
00451       break;
00452    case IAX_COMMAND_REJECT:
00453       cmd = "REJECT ";
00454       break;
00455    case IAX_COMMAND_ACCEPT:
00456       cmd = "ACCEPT ";
00457       break;
00458    case IAX_COMMAND_AUTHREQ:
00459       cmd = "AUTHREQ";
00460       break;
00461    case IAX_COMMAND_AUTHREP:
00462       cmd = "AUTHREP";
00463       break;
00464    case IAX_COMMAND_INVAL:
00465       cmd = "INVAL  ";
00466       break;
00467    case IAX_COMMAND_LAGRQ:
00468       cmd = "LAGRQ  ";
00469       break;
00470    case IAX_COMMAND_LAGRP:
00471       cmd = "LAGRP  ";
00472       break;
00473    case IAX_COMMAND_REGREQ:
00474       cmd = "REGREQ ";
00475       break;
00476    case IAX_COMMAND_REGAUTH:
00477       cmd = "REGAUTH";
00478       break;
00479    case IAX_COMMAND_REGACK:
00480       cmd = "REGACK ";
00481       break;
00482    case IAX_COMMAND_REGREJ:
00483       cmd = "REGREJ ";
00484       break;
00485    case IAX_COMMAND_REGREL:
00486       cmd = "REGREL ";
00487       break;
00488    case IAX_COMMAND_VNAK:
00489       cmd = "VNAK   ";
00490       break;
00491    case IAX_COMMAND_DPREQ:
00492       cmd = "DPREQ  ";
00493       break;
00494    case IAX_COMMAND_DPREP:
00495       cmd = "DPREP  ";
00496       break;
00497    case IAX_COMMAND_DIAL:
00498       cmd = "DIAL   ";
00499       break;
00500    case IAX_COMMAND_TXREQ:
00501       cmd = "TXREQ  ";
00502       break;
00503    case IAX_COMMAND_TXCNT:
00504       cmd = "TXCNT  ";
00505       break;
00506    case IAX_COMMAND_TXACC:
00507       cmd = "TXACC  ";
00508       break;
00509    case IAX_COMMAND_TXREADY:
00510       cmd = "TXREADY";
00511       break;
00512    case IAX_COMMAND_TXREL:
00513       cmd = "TXREL  ";
00514       break;
00515    case IAX_COMMAND_TXREJ:
00516       cmd = "TXREJ  ";
00517       break;
00518    case IAX_COMMAND_QUELCH:
00519       cmd = "QUELCH ";
00520       break;
00521    case IAX_COMMAND_UNQUELCH:
00522       cmd = "UNQULCH";
00523       break;
00524    case IAX_COMMAND_POKE:
00525       cmd = "POKE   ";
00526       break;
00527    case IAX_COMMAND_PAGE:
00528       cmd = "PAGE   ";
00529       break;
00530    case IAX_COMMAND_MWI:
00531       cmd = "MWI    ";
00532       break;
00533    case IAX_COMMAND_UNSUPPORT:
00534       cmd = "UNSPRTD";
00535       break;
00536    case IAX_COMMAND_TRANSFER:
00537       cmd = "TRANSFR";
00538       break;
00539    case IAX_COMMAND_PROVISION:
00540       cmd = "PROVISN";
00541       break;
00542    case IAX_COMMAND_FWDOWNL:
00543       cmd = "FWDWNLD";
00544       break;
00545    case IAX_COMMAND_FWDATA:
00546       cmd = "FWDATA ";
00547       break;
00548    case IAX_COMMAND_TXMEDIA:
00549       cmd = "TXMEDIA";
00550       break;
00551    case IAX_COMMAND_RTKEY:
00552       cmd = "RTKEY  ";
00553       break;
00554    case IAX_COMMAND_CALLTOKEN:
00555       cmd = "CTOKEN ";
00556       break;
00557    }
00558    ast_copy_string(str, cmd, len);
00559 }

void iax_frame_wrap ( struct iax_frame fr,
struct ast_frame f 
)

Definition at line 1138 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_subclass::codec, ast_frame::data, ast_frame::datalen, ast_frame::delivery, f, ast_frame::frametype, ast_frame::len, LOG_ERROR, ast_frame::mallocd, ast_frame::offset, ast_frame::ptr, ast_frame::samples, ast_frame::src, and ast_frame::subclass.

Referenced by iax2_send(), iaxfrdup2(), socket_process(), and socket_process_meta().

01139 {
01140    fr->af.frametype = f->frametype;
01141    fr->af.subclass.codec = f->subclass.codec;
01142    fr->af.mallocd = 0;           /* Our frame is static relative to the container */
01143    fr->af.datalen = f->datalen;
01144    fr->af.samples = f->samples;
01145    fr->af.offset = AST_FRIENDLY_OFFSET;
01146    fr->af.src = f->src;
01147    fr->af.delivery.tv_sec = 0;
01148    fr->af.delivery.tv_usec = 0;
01149    fr->af.data.ptr = fr->afdata;
01150    fr->af.len = f->len;
01151    if (fr->af.datalen) {
01152       size_t copy_len = fr->af.datalen;
01153       if (copy_len > fr->afdatalen) {
01154          ast_log(LOG_ERROR, "Losing frame data because destination buffer size '%d' bytes not big enough for '%d' bytes in the frame\n",
01155             (int) fr->afdatalen, (int) fr->af.datalen);
01156          copy_len = fr->afdatalen;
01157       }
01158 #if __BYTE_ORDER == __LITTLE_ENDIAN
01159       /* We need to byte-swap slinear samples from network byte order */
01160       if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass.codec == AST_FORMAT_SLINEAR)) {
01161          /* 2 bytes / sample for SLINEAR */
01162          ast_swapcopy_samples(fr->af.data.ptr, f->data.ptr, copy_len / 2);
01163       } else
01164 #endif
01165          memcpy(fr->af.data.ptr, f->data.ptr, copy_len);
01166    }
01167 }

int iax_get_frames ( void   ) 

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

Referenced by handle_cli_iax2_show_stats().

01279 { return frames; }

int iax_get_iframes ( void   ) 

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

Referenced by handle_cli_iax2_show_stats().

01280 { return iframes; }

int iax_get_oframes ( void   ) 

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

Referenced by handle_cli_iax2_show_stats().

01281 { return oframes; }

const char* iax_ie2str ( int  ie  ) 

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

References ARRAY_LEN, infoelts, and iax2_ie::name.

Referenced by iax_ie_append_raw(), and iax_parse_ies().

00321 {
00322    int x;
00323    for (x = 0; x < ARRAY_LEN(infoelts); x++) {
00324       if (infoelts[x].ie == ie)
00325          return infoelts[x].name;
00326    }
00327    return "Unknown IE";
00328 }

int iax_ie_append ( struct iax_ie_data ied,
unsigned char  ie 
)

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

References iax_ie_append_raw().

Referenced by iax2_call(), and iax_firmware_append().

00734 {
00735    return iax_ie_append_raw(ied, ie, NULL, 0);
00736 }

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

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

References iax_ie_append_raw().

Referenced by iax2_start_transfer(), and update_registry().

00695 {
00696    return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in));
00697 }

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

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

References iax_ie_append_raw().

Referenced by __auth_reject(), __auto_hangup(), authenticate_request(), iax2_call(), iax2_hangup(), iax_provision_build(), and socket_process().

00729 {
00730    return iax_ie_append_raw(ied, ie, &dat, 1);
00731 }

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

Definition at line 709 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_process(), try_transfer(), and update_registry().

00710 {
00711    unsigned int newval;
00712    newval = htonl(value);
00713    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00714 }

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

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

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

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

00680 {
00681    char tmp[256];
00682    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00683       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);
00684       errorf(tmp);
00685       return -1;
00686    }
00687    ied->buf[ied->pos++] = ie;
00688    ied->buf[ied->pos++] = datalen;
00689    memcpy(ied->buf + ied->pos, data, datalen);
00690    ied->pos += datalen;
00691    return 0;
00692 }

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

Definition at line 716 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_process(), and update_registry().

00717 {
00718    unsigned short newval;
00719    newval = htons(value);
00720    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00721 }

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

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

References iax_ie_append_raw().

Referenced by __auth_reject(), __auto_hangup(), authenticate(), authenticate_request(), cache_get_callno_locked(), dp_lookup(), handle_call_token(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_transfer(), iax_provision_build(), registry_authrequest(), registry_rerequest(), resend_with_token(), socket_process(), and update_registry().

00724 {
00725    return iax_ie_append_raw(ied, ie, str, strlen(str));
00726 }

int iax_ie_append_versioned_uint64 ( struct iax_ie_data ied,
unsigned char  ie,
unsigned char  version,
uint64_t  value 
)

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

References htonll(), iax_ie_append_raw(), and put_unaligned_uint64().

Referenced by iax2_call(), and socket_process().

00700 {
00701    struct _local {
00702       unsigned char version;
00703       uint64_t value;
00704    } __attribute__((packed)) newval = { version, };
00705    put_unaligned_uint64(&newval.value, htonll(value));
00706    return iax_ie_append_raw(ied, ie, &newval, (int) sizeof(newval));
00707 }

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

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

References iax_ies::adsicpe, iax_ies::apparent_addr, ast_copy_string(), ast_free, ast_str_buffer(), ast_str_create(), ast_str_set(), ast_variable_new(), 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, ast_variable::file, iax_ies::firmwarever, iax_ies::format, iax_ies::fwdata, iax_ies::fwdatalen, iax_ies::fwdesc, get_unaligned_uint16(), get_unaligned_uint32(), get_unaligned_uint64(), 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_CAPABILITY2, 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_FORMAT2, 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_OSPTOKEN, 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_VARIABLE, IAX_IE_VERSION, IAX_MAX_OSPBLOCK_NUM, IAX_RATE_8KHZ, iax_ies::iax_unknown, iax_ies::language, len(), iax_ies::md5_result, iax_ies::msgcount, iax_ies::musiconhold, ast_variable::name, ast_variable::next, ntohll(), iax_ies::ospblocklength, iax_ies::osptokenblock, 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, str, iax_ies::transferid, iax_ies::username, ast_variable::value, var, iax_ies::vars, iax_ies::version, and version.

Referenced by socket_process().

00749 {
00750    /* Parse data into information elements */
00751    int len;
00752    int ie;
00753    char tmp[256], *tmp2;
00754    struct ast_variable *var, *var2, *prev;
00755    unsigned int count;
00756    memset(ies, 0, (int)sizeof(struct iax_ies));
00757    ies->msgcount = -1;
00758    ies->firmwarever = -1;
00759    ies->calling_ton = -1;
00760    ies->calling_tns = -1;
00761    ies->calling_pres = -1;
00762    ies->samprate = IAX_RATE_8KHZ;
00763    while(datalen >= 2) {
00764       ie = data[0];
00765       len = data[1];
00766       if (len > datalen - 2) {
00767          errorf("Information element length exceeds message size\n");
00768          return -1;
00769       }
00770       switch(ie) {
00771       case IAX_IE_CALLED_NUMBER:
00772          ies->called_number = (char *)data + 2;
00773          break;
00774       case IAX_IE_CALLING_NUMBER:
00775          ies->calling_number = (char *)data + 2;
00776          break;
00777       case IAX_IE_CALLING_ANI:
00778          ies->calling_ani = (char *)data + 2;
00779          break;
00780       case IAX_IE_CALLING_NAME:
00781          ies->calling_name = (char *)data + 2;
00782          break;
00783       case IAX_IE_CALLED_CONTEXT:
00784          ies->called_context = (char *)data + 2;
00785          break;
00786       case IAX_IE_USERNAME:
00787          ies->username = (char *)data + 2;
00788          break;
00789       case IAX_IE_PASSWORD:
00790          ies->password = (char *)data + 2;
00791          break;
00792       case IAX_IE_CODEC_PREFS:
00793          ies->codec_prefs = (char *)data + 2;
00794          break;
00795       case IAX_IE_CAPABILITY:
00796          if (len != (int)sizeof(unsigned int)) {
00797             snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00798             errorf(tmp);
00799          } else if (ies->capability == 0) { /* Don't overwrite capability2, if specified */
00800             ies->capability = ntohl(get_unaligned_uint32(data + 2));
00801          }
00802          break;
00803       case IAX_IE_CAPABILITY2:
00804          {
00805             int version = data[2];
00806             if (version == 0) {
00807                if (len != (int)sizeof(char) + sizeof(format_t)) {
00808                   snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int) (sizeof(format_t) + sizeof(char)), len);
00809                   errorf(tmp);
00810                } else {
00811                   ies->capability = (format_t) ntohll(get_unaligned_uint64(data + 3));
00812                }
00813             } /* else unknown version */
00814          }
00815          break;
00816       case IAX_IE_FORMAT:
00817          if (len != (int)sizeof(unsigned int)) {
00818             snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00819             errorf(tmp);
00820          } else if (ies->format == 0) { /* Don't overwrite format2, if specified */
00821             ies->format = ntohl(get_unaligned_uint32(data + 2));
00822          }
00823          break;
00824       case IAX_IE_FORMAT2:
00825          {
00826             int version = data[2];
00827             if (version == 0) {
00828                if (len != (int)sizeof(char) + sizeof(format_t)) {
00829                   snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int) (sizeof(format_t) + sizeof(char)), len);
00830                   errorf(tmp);
00831                } else {
00832                   ies->format = (format_t) ntohll(get_unaligned_uint64(data + 3));
00833                }
00834             } /* else unknown version */
00835          }
00836          break;
00837       case IAX_IE_LANGUAGE:
00838          ies->language = (char *)data + 2;
00839          break;
00840       case IAX_IE_VERSION:
00841          if (len != (int)sizeof(unsigned short)) {
00842             snprintf(tmp, (int)sizeof(tmp),  "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00843             errorf(tmp);
00844          } else
00845             ies->version = ntohs(get_unaligned_uint16(data + 2));
00846          break;
00847       case IAX_IE_ADSICPE:
00848          if (len != (int)sizeof(unsigned short)) {
00849             snprintf(tmp, (int)sizeof(tmp), "Expecting adsicpe to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00850             errorf(tmp);
00851          } else
00852             ies->adsicpe = ntohs(get_unaligned_uint16(data + 2));
00853          break;
00854       case IAX_IE_SAMPLINGRATE:
00855          if (len != (int)sizeof(unsigned short)) {
00856             snprintf(tmp, (int)sizeof(tmp), "Expecting samplingrate to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00857             errorf(tmp);
00858          } else
00859             ies->samprate = ntohs(get_unaligned_uint16(data + 2));
00860          break;
00861       case IAX_IE_DNID:
00862          ies->dnid = (char *)data + 2;
00863          break;
00864       case IAX_IE_RDNIS:
00865          ies->rdnis = (char *)data + 2;
00866          break;
00867       case IAX_IE_AUTHMETHODS:
00868          if (len != (int)sizeof(unsigned short))  {
00869             snprintf(tmp, (int)sizeof(tmp), "Expecting authmethods to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00870             errorf(tmp);
00871          } else
00872             ies->authmethods = ntohs(get_unaligned_uint16(data + 2));
00873          break;
00874       case IAX_IE_ENCRYPTION:
00875          if (len != (int)sizeof(unsigned short))  {
00876             snprintf(tmp, (int)sizeof(tmp), "Expecting encryption to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00877             errorf(tmp);
00878          } else
00879             ies->encmethods = ntohs(get_unaligned_uint16(data + 2));
00880          break;
00881       case IAX_IE_CHALLENGE:
00882          ies->challenge = (char *)data + 2;
00883          break;
00884       case IAX_IE_MD5_RESULT:
00885          ies->md5_result = (char *)data + 2;
00886          break;
00887       case IAX_IE_RSA_RESULT:
00888          ies->rsa_result = (char *)data + 2;
00889          break;
00890       case IAX_IE_APPARENT_ADDR:
00891          ies->apparent_addr = ((struct sockaddr_in *)(data + 2));
00892          break;
00893       case IAX_IE_REFRESH:
00894          if (len != (int)sizeof(unsigned short)) {
00895             snprintf(tmp, (int)sizeof(tmp),  "Expecting refresh to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00896             errorf(tmp);
00897          } else
00898             ies->refresh = ntohs(get_unaligned_uint16(data + 2));
00899          break;
00900       case IAX_IE_DPSTATUS:
00901          if (len != (int)sizeof(unsigned short)) {
00902             snprintf(tmp, (int)sizeof(tmp),  "Expecting dpstatus to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00903             errorf(tmp);
00904          } else
00905             ies->dpstatus = ntohs(get_unaligned_uint16(data + 2));
00906          break;
00907       case IAX_IE_CALLNO:
00908          if (len != (int)sizeof(unsigned short)) {
00909             snprintf(tmp, (int)sizeof(tmp),  "Expecting callno to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00910             errorf(tmp);
00911          } else
00912             ies->callno = ntohs(get_unaligned_uint16(data + 2));
00913          break;
00914       case IAX_IE_CAUSE:
00915          ies->cause = (char *)data + 2;
00916          break;
00917       case IAX_IE_CAUSECODE:
00918          if (len != 1) {
00919             snprintf(tmp, (int)sizeof(tmp), "Expecting causecode to be single byte but was %d\n", len);
00920             errorf(tmp);
00921          } else {
00922             ies->causecode = data[2];
00923          }
00924          break;
00925       case IAX_IE_IAX_UNKNOWN:
00926          if (len == 1)
00927             ies->iax_unknown = data[2];
00928          else {
00929             snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len);
00930             errorf(tmp);
00931          }
00932          break;
00933       case IAX_IE_MSGCOUNT:
00934          if (len != (int)sizeof(unsigned short)) {
00935             snprintf(tmp, (int)sizeof(tmp), "Expecting msgcount to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00936             errorf(tmp);
00937          } else
00938             ies->msgcount = ntohs(get_unaligned_uint16(data + 2));   
00939          break;
00940       case IAX_IE_AUTOANSWER:
00941          ies->autoanswer = 1;
00942          break;
00943       case IAX_IE_MUSICONHOLD:
00944          ies->musiconhold = 1;
00945          break;
00946       case IAX_IE_TRANSFERID:
00947          if (len != (int)sizeof(unsigned int)) {
00948             snprintf(tmp, (int)sizeof(tmp), "Expecting transferid to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00949             errorf(tmp);
00950          } else
00951             ies->transferid = ntohl(get_unaligned_uint32(data + 2));
00952          break;
00953       case IAX_IE_DATETIME:
00954          if (len != (int)sizeof(unsigned int)) {
00955             snprintf(tmp, (int)sizeof(tmp), "Expecting date/time to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00956             errorf(tmp);
00957          } else
00958             ies->datetime = ntohl(get_unaligned_uint32(data + 2));
00959          break;
00960       case IAX_IE_FIRMWAREVER:
00961          if (len != (int)sizeof(unsigned short)) {
00962             snprintf(tmp, (int)sizeof(tmp), "Expecting firmwarever to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00963             errorf(tmp);
00964          } else
00965             ies->firmwarever = ntohs(get_unaligned_uint16(data + 2));   
00966          break;
00967       case IAX_IE_DEVICETYPE:
00968          ies->devicetype = (char *)data + 2;
00969          break;
00970       case IAX_IE_SERVICEIDENT:
00971          ies->serviceident = (char *)data + 2;
00972          break;
00973       case IAX_IE_FWBLOCKDESC:
00974          if (len != (int)sizeof(unsigned int)) {
00975             snprintf(tmp, (int)sizeof(tmp), "Expected block desc to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00976             errorf(tmp);
00977          } else
00978             ies->fwdesc = ntohl(get_unaligned_uint32(data + 2));
00979          break;
00980       case IAX_IE_FWBLOCKDATA:
00981          ies->fwdata = data + 2;
00982          ies->fwdatalen = len;
00983          break;
00984       case IAX_IE_ENCKEY:
00985          ies->enckey = data + 2;
00986          ies->enckeylen = len;
00987          break;
00988       case IAX_IE_PROVVER:
00989          if (len != (int)sizeof(unsigned int)) {
00990             snprintf(tmp, (int)sizeof(tmp), "Expected provisioning version to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00991             errorf(tmp);
00992          } else {
00993             ies->provverpres = 1;
00994             ies->provver = ntohl(get_unaligned_uint32(data + 2));
00995          }
00996          break;
00997       case IAX_IE_CALLINGPRES:
00998          if (len == 1)
00999             ies->calling_pres = data[2];
01000          else {
01001             snprintf(tmp, (int)sizeof(tmp), "Expected single byte callingpres, but was %d long\n", len);
01002             errorf(tmp);
01003          }
01004          break;
01005       case IAX_IE_CALLINGTON:
01006          if (len == 1)
01007             ies->calling_ton = data[2];
01008          else {
01009             snprintf(tmp, (int)sizeof(tmp), "Expected single byte callington, but was %d long\n", len);
01010             errorf(tmp);
01011          }
01012          break;
01013       case IAX_IE_CALLINGTNS:
01014          if (len != (int)sizeof(unsigned short)) {
01015             snprintf(tmp, (int)sizeof(tmp), "Expecting callingtns to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
01016             errorf(tmp);
01017          } else
01018             ies->calling_tns = ntohs(get_unaligned_uint16(data + 2));   
01019          break;
01020                case IAX_IE_RR_JITTER:
01021                        if (len != (int)sizeof(unsigned int)) {
01022                                snprintf(tmp, (int)sizeof(tmp), "Expected jitter rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
01023                                errorf(tmp);
01024                        } else {
01025                                ies->rr_jitter = ntohl(get_unaligned_uint32(data + 2));
01026                        }
01027                        break;
01028                case IAX_IE_RR_LOSS:
01029                        if (len != (int)sizeof(unsigned int)) {
01030                                snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
01031                                errorf(tmp);
01032                        } else {
01033                                ies->rr_loss = ntohl(get_unaligned_uint32(data + 2));
01034                        }
01035                        break;
01036                case IAX_IE_RR_PKTS:
01037                        if (len != (int)sizeof(unsigned int)) {
01038                                snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
01039                                errorf(tmp);
01040                        } else {
01041                                ies->rr_pkts = ntohl(get_unaligned_uint32(data + 2));
01042                        }
01043                        break;
01044                case IAX_IE_RR_DELAY:
01045                        if (len != (int)sizeof(unsigned short)) {
01046                                snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
01047                         errorf(tmp);
01048                        } else {
01049                                ies->rr_delay = ntohs(get_unaligned_uint16(data + 2));
01050                        }
01051                        break;
01052       case IAX_IE_RR_DROPPED:
01053          if (len != (int)sizeof(unsigned int)) {
01054             snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
01055             errorf(tmp);
01056          } else {
01057             ies->rr_dropped = ntohl(get_unaligned_uint32(data + 2));
01058          }
01059          break;
01060       case IAX_IE_RR_OOO:
01061          if (len != (int)sizeof(unsigned int)) {
01062             snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
01063             errorf(tmp);
01064          } else {
01065             ies->rr_ooo = ntohl(get_unaligned_uint32(data + 2));
01066          }
01067          break;
01068       case IAX_IE_VARIABLE:
01069          ast_copy_string(tmp, (char *)data + 2, len + 1);
01070          tmp2 = strchr(tmp, '=');
01071          if (tmp2)
01072             *tmp2++ = '\0';
01073          else
01074             tmp2 = "";
01075          {
01076             struct ast_str *str = ast_str_create(16);
01077             /* Existing variable or new variable? */
01078             for (var2 = ies->vars, prev = NULL; var2; prev = var2, var2 = var2->next) {
01079                if (strcmp(tmp, var2->name) == 0) {
01080                   ast_str_set(&str, 0, "%s%s", var2->value, tmp2);
01081                   var = ast_variable_new(tmp, ast_str_buffer(str), var2->file);
01082                   var->next = var2->next;
01083                   if (prev) {
01084                      prev->next = var;
01085                   } else {
01086                      ies->vars = var;
01087                   }
01088                   snprintf(tmp, sizeof(tmp), "Assigned (%p)%s to (%p)%s\n", var->name, var->name, var->value, var->value);
01089                   outputf(tmp);
01090                   ast_free(var2);
01091                   break;
01092                }
01093             }
01094             ast_free(str);
01095          }
01096 
01097          if (!var2) {
01098             var = ast_variable_new(tmp, tmp2, "");
01099             snprintf(tmp, sizeof(tmp), "Assigned (%p)%s to (%p)%s\n", var->name, var->name, var->value, var->value);
01100             outputf(tmp);
01101             var->next = ies->vars;
01102             ies->vars = var;
01103          }
01104          break;
01105       case IAX_IE_OSPTOKEN:
01106          if ((count = data[2]) < IAX_MAX_OSPBLOCK_NUM) {
01107             ies->osptokenblock[count] = (char *)data + 2 + 1;
01108             ies->ospblocklength[count] = len - 1;
01109          } else {
01110             snprintf(tmp, (int)sizeof(tmp), "Expected OSP token block index to be 0~%d but was %d\n", IAX_MAX_OSPBLOCK_NUM - 1, count);
01111             errorf(tmp);
01112          }
01113          break;
01114       case IAX_IE_CALLTOKEN:
01115          if (len) {
01116             ies->calltokendata = (unsigned char *) data + 2;
01117          }
01118          ies->calltoken = 1;
01119          break;
01120       default:
01121          snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len);
01122          outputf(tmp);
01123       }
01124       /* Overwrite information element with 0, to null terminate previous portion */
01125       data[0] = 0;
01126       datalen -= (len + 2);
01127       data += (len + 2);
01128    }
01129    /* Null-terminate last field */
01130    *data = '\0';
01131    if (datalen) {
01132       errorf("Invalid information element contents, strange boundary\n");
01133       return -1;
01134    }
01135    return 0;
01136 }

void iax_set_error ( void(*)(const char *data)  output  ) 

void iax_set_output ( void(*)(const char *data)  output  ) 

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

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

References ARRAY_LEN, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_IAX, ast_inet_ntoa(), ast_iax2_full_hdr::csub, ast_iax2_full_hdr::dcallno, dump_ies(), f, IAX_FLAG_FULL, IAX_FLAG_RETRANS, iax_frame_subclass2str(), ast_iax2_full_hdr::iedata, ast_iax2_full_hdr::iseqno, ast_iax2_full_hdr::oseqno, outputf, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::ts, and ast_iax2_full_hdr::type.

Referenced by iax_outputframe(), and send_packet().

00562 {
00563    const char *framelist[] = {
00564       "(0?)",
00565       "DTMF_E ",
00566       "VOICE  ",
00567       "VIDEO  ",
00568       "CONTROL",
00569       "NULL   ",
00570       "IAX    ",
00571       "TEXT   ",
00572       "IMAGE  ",
00573       "HTML   ",
00574       "CNG    ",
00575       "MODEM  ",
00576       "DTMF_B ",
00577    };
00578    const char *cmds[] = {
00579       "(0?)",
00580       "HANGUP ",
00581       "RING   ",
00582       "RINGING",
00583       "ANSWER ",
00584       "BUSY   ",
00585       "TKOFFHK",
00586       "OFFHOOK",
00587       "CONGSTN",
00588       "FLASH  ",
00589       "WINK   ",
00590       "OPTION ",
00591       "RDKEY  ",
00592       "RDUNKEY",
00593       "PROGRES",
00594       "PROCDNG",
00595       "HOLD   ",
00596       "UNHOLD ",
00597       "VIDUPDT",
00598       "T38    ",
00599       "SRCUPDT",
00600       "TXFER  ",
00601       "CNLINE ",
00602       "REDIR  ",
00603    };
00604    struct ast_iax2_full_hdr *fh;
00605    char retries[20];
00606    char class2[20];
00607    char subclass2[20];
00608    const char *class;
00609    const char *subclass;
00610    char *dir;
00611    char tmp[512];
00612 
00613    switch(rx) {
00614    case 0:
00615       dir = "Tx";
00616       break;
00617    case 2:
00618       dir = "TE";
00619       break;
00620    case 3:
00621       dir = "RD";
00622       break;
00623    default:
00624       dir = "Rx";
00625       break;
00626    }
00627    if (f) {
00628       fh = f->data;
00629       snprintf(retries, sizeof(retries), "%03d", f->retries);
00630    } else {
00631       fh = fhi;
00632       if (ntohs(fh->dcallno) & IAX_FLAG_RETRANS)
00633          strcpy(retries, "Yes");
00634       else
00635          strcpy(retries, " No");
00636    }
00637    if (!(ntohs(fh->scallno) & IAX_FLAG_FULL)) {
00638       /* Don't mess with mini-frames */
00639       return;
00640    }
00641    if (fh->type >= ARRAY_LEN(framelist)) {
00642       snprintf(class2, sizeof(class2), "(%d?)", fh->type);
00643       class = class2;
00644    } else {
00645       class = framelist[(int)fh->type];
00646    }
00647    if (fh->type == AST_FRAME_DTMF_BEGIN || fh->type == AST_FRAME_DTMF_END) {
00648       sprintf(subclass2, "%c", fh->csub);
00649       subclass = subclass2;
00650    } else if (fh->type == AST_FRAME_IAX) {
00651          iax_frame_subclass2str((int)fh->csub, subclass2, sizeof(subclass2));
00652          subclass = subclass2;
00653    } else if (fh->type == AST_FRAME_CONTROL) {
00654       if (fh->csub >= ARRAY_LEN(cmds)) {
00655          snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub);
00656          subclass = subclass2;
00657       } else {
00658          subclass = cmds[(int)fh->csub];
00659       }
00660    } else {
00661       snprintf(subclass2, sizeof(subclass2), "%d", fh->csub);
00662       subclass = subclass2;
00663    }
00664    snprintf(tmp, sizeof(tmp), 
00665        "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s Subclass: %s\n",
00666        dir,
00667        retries, fh->oseqno, fh->iseqno, class, subclass);
00668    outputf(tmp);
00669    snprintf(tmp, sizeof(tmp), 
00670        "   Timestamp: %05lums  SCall: %5.5d  DCall: %5.5d [%s:%d]\n",
00671        (unsigned long)ntohl(fh->ts),
00672        ntohs(fh->scallno) & ~IAX_FLAG_FULL, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS,
00673        ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
00674    outputf(tmp);
00675    if (fh->type == AST_FRAME_IAX)
00676       dump_ies(fh->iedata, datalen);
00677 }


Generated on Mon Mar 19 11:30:48 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7