#include "asterisk/linkedlists.h"
#include "asterisk/aes.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_frame * | iax_frame_new (int direction, int datalen, unsigned int cacheable) |
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_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) |
Definition in file iax2-parser.h.
#define DIRECTION_INGRESS 1 |
Definition at line 82 of file iax2-parser.h.
Referenced by iax_frame_free(), iax_frame_new(), and iaxfrdup2().
#define DIRECTION_OUTGRESS 2 |
Definition at line 83 of file iax2-parser.h.
Referenced by iax2_send(), iax_frame_free(), and send_trunk().
void iax_frame_free | ( | struct iax_frame * | fr | ) |
Definition at line 1072 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 network_thread().
01073 { 01074 #if !defined(LOW_MEMORY) 01075 struct iax_frames *iax_frames = NULL; 01076 #endif 01077 01078 /* Note: does not remove from scheduler! */ 01079 if (fr->direction == DIRECTION_INGRESS) 01080 ast_atomic_fetchadd_int(&iframes, -1); 01081 else if (fr->direction == DIRECTION_OUTGRESS) 01082 ast_atomic_fetchadd_int(&oframes, -1); 01083 else { 01084 errorf("Attempt to double free frame detected\n"); 01085 return; 01086 } 01087 ast_atomic_fetchadd_int(&frames, -1); 01088 01089 #if !defined(LOW_MEMORY) 01090 if (!fr->cacheable || !(iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) { 01091 ast_free(fr); 01092 return; 01093 } 01094 01095 if (iax_frames->size < FRAME_CACHE_MAX_SIZE) { 01096 fr->direction = 0; 01097 /* Pseudo-sort: keep smaller frames at the top of the list. This should 01098 * increase the chance that we pick the smallest applicable frame for use. */ 01099 if (AST_LIST_FIRST(&iax_frames->list) && AST_LIST_FIRST(&iax_frames->list)->afdatalen < fr->afdatalen) { 01100 AST_LIST_INSERT_TAIL(&iax_frames->list, fr, list); 01101 } else { 01102 AST_LIST_INSERT_HEAD(&iax_frames->list, fr, list); 01103 } 01104 iax_frames->size++; 01105 return; 01106 } 01107 #endif 01108 ast_free(fr); 01109 }
struct iax_frame* iax_frame_new | ( | int | direction, | |
int | datalen, | |||
unsigned int | cacheable | |||
) |
Definition at line 1014 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().
01015 { 01016 struct iax_frame *fr = NULL; 01017 01018 #if !defined(LOW_MEMORY) 01019 struct iax_frames *iax_frames = NULL; 01020 struct iax_frame *smallest = NULL; 01021 01022 /* Attempt to get a frame from this thread's cache */ 01023 if ((iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) { 01024 smallest = AST_LIST_FIRST(&iax_frames->list); 01025 AST_LIST_TRAVERSE_SAFE_BEGIN(&iax_frames->list, fr, list) { 01026 if (fr->afdatalen >= datalen) { 01027 size_t afdatalen = fr->afdatalen; 01028 AST_LIST_REMOVE_CURRENT(list); 01029 iax_frames->size--; 01030 memset(fr, 0, sizeof(*fr)); 01031 fr->afdatalen = afdatalen; 01032 break; 01033 } else if (smallest->afdatalen > fr->afdatalen) { 01034 smallest = fr; 01035 } 01036 } 01037 AST_LIST_TRAVERSE_SAFE_END; 01038 } 01039 if (!fr) { 01040 if (iax_frames->size >= FRAME_CACHE_MAX_SIZE && smallest) { 01041 /* Make useless cache into something more useful */ 01042 AST_LIST_REMOVE(&iax_frames->list, smallest, list); 01043 if (!(fr = ast_realloc(smallest, sizeof(*fr) + datalen))) { 01044 AST_LIST_INSERT_TAIL(&iax_frames->list, smallest, list); 01045 return NULL; 01046 } 01047 } else if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen))) 01048 return NULL; 01049 fr->afdatalen = datalen; 01050 } 01051 #else 01052 if (!(fr = ast_calloc(1, sizeof(*fr) + datalen))) 01053 return NULL; 01054 fr->afdatalen = datalen; 01055 #endif 01056 01057 01058 fr->direction = direction; 01059 fr->retrans = -1; 01060 fr->cacheable = cacheable; 01061 01062 if (fr->direction == DIRECTION_INGRESS) 01063 ast_atomic_fetchadd_int(&iframes, 1); 01064 else 01065 ast_atomic_fetchadd_int(&oframes, 1); 01066 01067 ast_atomic_fetchadd_int(&frames, 1); 01068 01069 return fr; 01070 }
Definition at line 983 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, 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().
00984 { 00985 fr->af.frametype = f->frametype; 00986 fr->af.subclass = f->subclass; 00987 fr->af.mallocd = 0; /* Our frame is static relative to the container */ 00988 fr->af.datalen = f->datalen; 00989 fr->af.samples = f->samples; 00990 fr->af.offset = AST_FRIENDLY_OFFSET; 00991 fr->af.src = f->src; 00992 fr->af.delivery.tv_sec = 0; 00993 fr->af.delivery.tv_usec = 0; 00994 fr->af.data.ptr = fr->afdata; 00995 fr->af.len = f->len; 00996 if (fr->af.datalen) { 00997 size_t copy_len = fr->af.datalen; 00998 if (copy_len > fr->afdatalen) { 00999 ast_log(LOG_ERROR, "Losing frame data because destination buffer size '%d' bytes not big enough for '%d' bytes in the frame\n", 01000 (int) fr->afdatalen, (int) fr->af.datalen); 01001 copy_len = fr->afdatalen; 01002 } 01003 #if __BYTE_ORDER == __LITTLE_ENDIAN 01004 /* We need to byte-swap slinear samples from network byte order */ 01005 if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass == AST_FORMAT_SLINEAR)) { 01006 /* 2 bytes / sample for SLINEAR */ 01007 ast_swapcopy_samples(fr->af.data.ptr, f->data.ptr, copy_len / 2); 01008 } else 01009 #endif 01010 memcpy(fr->af.data.ptr, f->data.ptr, copy_len); 01011 } 01012 }
int iax_get_frames | ( | void | ) |
Definition at line 1124 of file iax2-parser.c.
Referenced by handle_cli_iax2_show_stats().
01124 { return frames; }
int iax_get_iframes | ( | void | ) |
Definition at line 1125 of file iax2-parser.c.
Referenced by handle_cli_iax2_show_stats().
01125 { return iframes; }
int iax_get_oframes | ( | void | ) |
Definition at line 1126 of file iax2-parser.c.
Referenced by handle_cli_iax2_show_stats().
01126 { return oframes; }
const char* iax_ie2str | ( | int | ie | ) |
Definition at line 302 of file iax2-parser.c.
References ARRAY_LEN, infoelts, and iax2_ie::name.
Referenced by iax_ie_append_raw(), and iax_parse_ies().
00303 { 00304 int x; 00305 for (x = 0; x < ARRAY_LEN(infoelts); x++) { 00306 if (infoelts[x].ie == ie) 00307 return infoelts[x].name; 00308 } 00309 return "Unknown IE"; 00310 }
int iax_ie_append | ( | struct iax_ie_data * | ied, | |
unsigned char | ie | |||
) |
Definition at line 612 of file iax2-parser.c.
References iax_ie_append_raw().
Referenced by iax2_call(), and iax_firmware_append().
00613 { 00614 return iax_ie_append_raw(ied, ie, NULL, 0); 00615 }
int iax_ie_append_addr | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
const struct sockaddr_in * | sin | |||
) |
Definition at line 583 of file iax2-parser.c.
References iax_ie_append_raw().
Referenced by iax2_start_transfer(), and update_registry().
00584 { 00585 return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in)); 00586 }
int iax_ie_append_byte | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
unsigned char | dat | |||
) |
Definition at line 607 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().
00608 { 00609 return iax_ie_append_raw(ied, ie, &dat, 1); 00610 }
int iax_ie_append_int | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
unsigned int | value | |||
) |
Definition at line 588 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().
00589 { 00590 unsigned int newval; 00591 newval = htonl(value); 00592 return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval)); 00593 }
int iax_ie_append_raw | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
const void * | data, | |||
int | datalen | |||
) |
Definition at line 568 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(), and iax_ie_append_str().
00569 { 00570 char tmp[256]; 00571 if (datalen > ((int)sizeof(ied->buf) - ied->pos)) { 00572 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); 00573 errorf(tmp); 00574 return -1; 00575 } 00576 ied->buf[ied->pos++] = ie; 00577 ied->buf[ied->pos++] = datalen; 00578 memcpy(ied->buf + ied->pos, data, datalen); 00579 ied->pos += datalen; 00580 return 0; 00581 }
int iax_ie_append_short | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
unsigned short | value | |||
) |
Definition at line 595 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().
00596 { 00597 unsigned short newval; 00598 newval = htons(value); 00599 return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval)); 00600 }
int iax_ie_append_str | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
const char * | str | |||
) |
Definition at line 602 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(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_transfer(), iax_provision_build(), registry_authrequest(), registry_rerequest(), socket_process(), and update_registry().
00603 { 00604 return iax_ie_append_raw(ied, ie, str, strlen(str)); 00605 }
int iax_parse_ies | ( | struct iax_ies * | ies, | |
unsigned char * | data, | |||
int | datalen | |||
) |
Definition at line 627 of file iax2-parser.c.
References iax_ies::adsicpe, iax_ies::apparent_addr, ast_copy_string(), ast_free, 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::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(), 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_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_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, 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, and iax_ies::version.
Referenced by socket_process().
00628 { 00629 /* Parse data into information elements */ 00630 int len; 00631 int ie; 00632 char tmp[256], *tmp2; 00633 struct ast_variable *var, *var2, *prev; 00634 unsigned int count; 00635 memset(ies, 0, (int)sizeof(struct iax_ies)); 00636 ies->msgcount = -1; 00637 ies->firmwarever = -1; 00638 ies->calling_ton = -1; 00639 ies->calling_tns = -1; 00640 ies->calling_pres = -1; 00641 ies->samprate = IAX_RATE_8KHZ; 00642 while(datalen >= 2) { 00643 ie = data[0]; 00644 len = data[1]; 00645 if (len > datalen - 2) { 00646 errorf("Information element length exceeds message size\n"); 00647 return -1; 00648 } 00649 switch(ie) { 00650 case IAX_IE_CALLED_NUMBER: 00651 ies->called_number = (char *)data + 2; 00652 break; 00653 case IAX_IE_CALLING_NUMBER: 00654 ies->calling_number = (char *)data + 2; 00655 break; 00656 case IAX_IE_CALLING_ANI: 00657 ies->calling_ani = (char *)data + 2; 00658 break; 00659 case IAX_IE_CALLING_NAME: 00660 ies->calling_name = (char *)data + 2; 00661 break; 00662 case IAX_IE_CALLED_CONTEXT: 00663 ies->called_context = (char *)data + 2; 00664 break; 00665 case IAX_IE_USERNAME: 00666 ies->username = (char *)data + 2; 00667 break; 00668 case IAX_IE_PASSWORD: 00669 ies->password = (char *)data + 2; 00670 break; 00671 case IAX_IE_CODEC_PREFS: 00672 ies->codec_prefs = (char *)data + 2; 00673 break; 00674 case IAX_IE_CAPABILITY: 00675 if (len != (int)sizeof(unsigned int)) { 00676 snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00677 errorf(tmp); 00678 } else 00679 ies->capability = ntohl(get_unaligned_uint32(data + 2)); 00680 break; 00681 case IAX_IE_FORMAT: 00682 if (len != (int)sizeof(unsigned int)) { 00683 snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00684 errorf(tmp); 00685 } else 00686 ies->format = ntohl(get_unaligned_uint32(data + 2)); 00687 break; 00688 case IAX_IE_LANGUAGE: 00689 ies->language = (char *)data + 2; 00690 break; 00691 case IAX_IE_VERSION: 00692 if (len != (int)sizeof(unsigned short)) { 00693 snprintf(tmp, (int)sizeof(tmp), "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00694 errorf(tmp); 00695 } else 00696 ies->version = ntohs(get_unaligned_uint16(data + 2)); 00697 break; 00698 case IAX_IE_ADSICPE: 00699 if (len != (int)sizeof(unsigned short)) { 00700 snprintf(tmp, (int)sizeof(tmp), "Expecting adsicpe to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00701 errorf(tmp); 00702 } else 00703 ies->adsicpe = ntohs(get_unaligned_uint16(data + 2)); 00704 break; 00705 case IAX_IE_SAMPLINGRATE: 00706 if (len != (int)sizeof(unsigned short)) { 00707 snprintf(tmp, (int)sizeof(tmp), "Expecting samplingrate to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00708 errorf(tmp); 00709 } else 00710 ies->samprate = ntohs(get_unaligned_uint16(data + 2)); 00711 break; 00712 case IAX_IE_DNID: 00713 ies->dnid = (char *)data + 2; 00714 break; 00715 case IAX_IE_RDNIS: 00716 ies->rdnis = (char *)data + 2; 00717 break; 00718 case IAX_IE_AUTHMETHODS: 00719 if (len != (int)sizeof(unsigned short)) { 00720 snprintf(tmp, (int)sizeof(tmp), "Expecting authmethods to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00721 errorf(tmp); 00722 } else 00723 ies->authmethods = ntohs(get_unaligned_uint16(data + 2)); 00724 break; 00725 case IAX_IE_ENCRYPTION: 00726 if (len != (int)sizeof(unsigned short)) { 00727 snprintf(tmp, (int)sizeof(tmp), "Expecting encryption to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00728 errorf(tmp); 00729 } else 00730 ies->encmethods = ntohs(get_unaligned_uint16(data + 2)); 00731 break; 00732 case IAX_IE_CHALLENGE: 00733 ies->challenge = (char *)data + 2; 00734 break; 00735 case IAX_IE_MD5_RESULT: 00736 ies->md5_result = (char *)data + 2; 00737 break; 00738 case IAX_IE_RSA_RESULT: 00739 ies->rsa_result = (char *)data + 2; 00740 break; 00741 case IAX_IE_APPARENT_ADDR: 00742 ies->apparent_addr = ((struct sockaddr_in *)(data + 2)); 00743 break; 00744 case IAX_IE_REFRESH: 00745 if (len != (int)sizeof(unsigned short)) { 00746 snprintf(tmp, (int)sizeof(tmp), "Expecting refresh to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00747 errorf(tmp); 00748 } else 00749 ies->refresh = ntohs(get_unaligned_uint16(data + 2)); 00750 break; 00751 case IAX_IE_DPSTATUS: 00752 if (len != (int)sizeof(unsigned short)) { 00753 snprintf(tmp, (int)sizeof(tmp), "Expecting dpstatus to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00754 errorf(tmp); 00755 } else 00756 ies->dpstatus = ntohs(get_unaligned_uint16(data + 2)); 00757 break; 00758 case IAX_IE_CALLNO: 00759 if (len != (int)sizeof(unsigned short)) { 00760 snprintf(tmp, (int)sizeof(tmp), "Expecting callno to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00761 errorf(tmp); 00762 } else 00763 ies->callno = ntohs(get_unaligned_uint16(data + 2)); 00764 break; 00765 case IAX_IE_CAUSE: 00766 ies->cause = (char *)data + 2; 00767 break; 00768 case IAX_IE_CAUSECODE: 00769 if (len != 1) { 00770 snprintf(tmp, (int)sizeof(tmp), "Expecting causecode to be single byte but was %d\n", len); 00771 errorf(tmp); 00772 } else { 00773 ies->causecode = data[2]; 00774 } 00775 break; 00776 case IAX_IE_IAX_UNKNOWN: 00777 if (len == 1) 00778 ies->iax_unknown = data[2]; 00779 else { 00780 snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len); 00781 errorf(tmp); 00782 } 00783 break; 00784 case IAX_IE_MSGCOUNT: 00785 if (len != (int)sizeof(unsigned short)) { 00786 snprintf(tmp, (int)sizeof(tmp), "Expecting msgcount to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00787 errorf(tmp); 00788 } else 00789 ies->msgcount = ntohs(get_unaligned_uint16(data + 2)); 00790 break; 00791 case IAX_IE_AUTOANSWER: 00792 ies->autoanswer = 1; 00793 break; 00794 case IAX_IE_MUSICONHOLD: 00795 ies->musiconhold = 1; 00796 break; 00797 case IAX_IE_TRANSFERID: 00798 if (len != (int)sizeof(unsigned int)) { 00799 snprintf(tmp, (int)sizeof(tmp), "Expecting transferid to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00800 errorf(tmp); 00801 } else 00802 ies->transferid = ntohl(get_unaligned_uint32(data + 2)); 00803 break; 00804 case IAX_IE_DATETIME: 00805 if (len != (int)sizeof(unsigned int)) { 00806 snprintf(tmp, (int)sizeof(tmp), "Expecting date/time to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00807 errorf(tmp); 00808 } else 00809 ies->datetime = ntohl(get_unaligned_uint32(data + 2)); 00810 break; 00811 case IAX_IE_FIRMWAREVER: 00812 if (len != (int)sizeof(unsigned short)) { 00813 snprintf(tmp, (int)sizeof(tmp), "Expecting firmwarever to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00814 errorf(tmp); 00815 } else 00816 ies->firmwarever = ntohs(get_unaligned_uint16(data + 2)); 00817 break; 00818 case IAX_IE_DEVICETYPE: 00819 ies->devicetype = (char *)data + 2; 00820 break; 00821 case IAX_IE_SERVICEIDENT: 00822 ies->serviceident = (char *)data + 2; 00823 break; 00824 case IAX_IE_FWBLOCKDESC: 00825 if (len != (int)sizeof(unsigned int)) { 00826 snprintf(tmp, (int)sizeof(tmp), "Expected block desc to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00827 errorf(tmp); 00828 } else 00829 ies->fwdesc = ntohl(get_unaligned_uint32(data + 2)); 00830 break; 00831 case IAX_IE_FWBLOCKDATA: 00832 ies->fwdata = data + 2; 00833 ies->fwdatalen = len; 00834 break; 00835 case IAX_IE_ENCKEY: 00836 ies->enckey = data + 2; 00837 ies->enckeylen = len; 00838 break; 00839 case IAX_IE_PROVVER: 00840 if (len != (int)sizeof(unsigned int)) { 00841 snprintf(tmp, (int)sizeof(tmp), "Expected provisioning version to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00842 errorf(tmp); 00843 } else { 00844 ies->provverpres = 1; 00845 ies->provver = ntohl(get_unaligned_uint32(data + 2)); 00846 } 00847 break; 00848 case IAX_IE_CALLINGPRES: 00849 if (len == 1) 00850 ies->calling_pres = data[2]; 00851 else { 00852 snprintf(tmp, (int)sizeof(tmp), "Expected single byte callingpres, but was %d long\n", len); 00853 errorf(tmp); 00854 } 00855 break; 00856 case IAX_IE_CALLINGTON: 00857 if (len == 1) 00858 ies->calling_ton = data[2]; 00859 else { 00860 snprintf(tmp, (int)sizeof(tmp), "Expected single byte callington, but was %d long\n", len); 00861 errorf(tmp); 00862 } 00863 break; 00864 case IAX_IE_CALLINGTNS: 00865 if (len != (int)sizeof(unsigned short)) { 00866 snprintf(tmp, (int)sizeof(tmp), "Expecting callingtns to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00867 errorf(tmp); 00868 } else 00869 ies->calling_tns = ntohs(get_unaligned_uint16(data + 2)); 00870 break; 00871 case IAX_IE_RR_JITTER: 00872 if (len != (int)sizeof(unsigned int)) { 00873 snprintf(tmp, (int)sizeof(tmp), "Expected jitter rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00874 errorf(tmp); 00875 } else { 00876 ies->rr_jitter = ntohl(get_unaligned_uint32(data + 2)); 00877 } 00878 break; 00879 case IAX_IE_RR_LOSS: 00880 if (len != (int)sizeof(unsigned int)) { 00881 snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00882 errorf(tmp); 00883 } else { 00884 ies->rr_loss = ntohl(get_unaligned_uint32(data + 2)); 00885 } 00886 break; 00887 case IAX_IE_RR_PKTS: 00888 if (len != (int)sizeof(unsigned int)) { 00889 snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00890 errorf(tmp); 00891 } else { 00892 ies->rr_pkts = ntohl(get_unaligned_uint32(data + 2)); 00893 } 00894 break; 00895 case IAX_IE_RR_DELAY: 00896 if (len != (int)sizeof(unsigned short)) { 00897 snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00898 errorf(tmp); 00899 } else { 00900 ies->rr_delay = ntohs(get_unaligned_uint16(data + 2)); 00901 } 00902 break; 00903 case IAX_IE_RR_DROPPED: 00904 if (len != (int)sizeof(unsigned int)) { 00905 snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00906 errorf(tmp); 00907 } else { 00908 ies->rr_dropped = ntohl(get_unaligned_uint32(data + 2)); 00909 } 00910 break; 00911 case IAX_IE_RR_OOO: 00912 if (len != (int)sizeof(unsigned int)) { 00913 snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00914 errorf(tmp); 00915 } else { 00916 ies->rr_ooo = ntohl(get_unaligned_uint32(data + 2)); 00917 } 00918 break; 00919 case IAX_IE_VARIABLE: 00920 ast_copy_string(tmp, (char *)data + 2, len + 1); 00921 tmp2 = strchr(tmp, '='); 00922 if (tmp2) 00923 *tmp2++ = '\0'; 00924 else 00925 tmp2 = ""; 00926 { 00927 struct ast_str *str = ast_str_create(16); 00928 /* Existing variable or new variable? */ 00929 for (var2 = ies->vars, prev = NULL; var2; prev = var2, var2 = var2->next) { 00930 if (strcmp(tmp, var2->name) == 0) { 00931 ast_str_set(&str, 0, "%s%s", var2->value, tmp2); 00932 var = ast_variable_new(tmp, str->str, var2->file); 00933 var->next = var2->next; 00934 if (prev) { 00935 prev->next = var; 00936 } else { 00937 ies->vars = var; 00938 } 00939 snprintf(tmp, sizeof(tmp), "Assigned (%p)%s to (%p)%s\n", var->name, var->name, var->value, var->value); 00940 errorf(tmp); 00941 ast_free(var2); 00942 break; 00943 } 00944 } 00945 ast_free(str); 00946 } 00947 00948 if (!var2) { 00949 var = ast_variable_new(tmp, tmp2, ""); 00950 snprintf(tmp, sizeof(tmp), "Assigned (%p)%s to (%p)%s\n", var->name, var->name, var->value, var->value); 00951 errorf(tmp); 00952 var->next = ies->vars; 00953 ies->vars = var; 00954 } 00955 break; 00956 case IAX_IE_OSPTOKEN: 00957 if ((count = data[2]) < IAX_MAX_OSPBLOCK_NUM) { 00958 ies->osptokenblock[count] = (char *)data + 2 + 1; 00959 ies->ospblocklength[count] = len - 1; 00960 } else { 00961 snprintf(tmp, (int)sizeof(tmp), "Expected OSP token block index to be 0~%d but was %d\n", IAX_MAX_OSPBLOCK_NUM - 1, count); 00962 errorf(tmp); 00963 } 00964 break; 00965 default: 00966 snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len); 00967 outputf(tmp); 00968 } 00969 /* Overwrite information element with 0, to null terminate previous portion */ 00970 data[0] = 0; 00971 datalen -= (len + 2); 00972 data += (len + 2); 00973 } 00974 /* Null-terminate last field */ 00975 *data = '\0'; 00976 if (datalen) { 00977 errorf("Invalid information element contents, strange boundary\n"); 00978 return -1; 00979 } 00980 return 0; 00981 }
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 411 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, dir, dump_ies(), f, IAX_FLAG_FULL, IAX_FLAG_RETRANS, iaxs, 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().
00412 { 00413 const char *framelist[] = { 00414 "(0?)", 00415 "DTMF_E ", 00416 "VOICE ", 00417 "VIDEO ", 00418 "CONTROL", 00419 "NULL ", 00420 "IAX ", 00421 "TEXT ", 00422 "IMAGE ", 00423 "HTML ", 00424 "CNG ", 00425 "MODEM ", 00426 "DTMF_B ", 00427 }; 00428 const char *iaxs[] = { 00429 "(0?)", 00430 "NEW ", 00431 "PING ", 00432 "PONG ", 00433 "ACK ", 00434 "HANGUP ", 00435 "REJECT ", 00436 "ACCEPT ", 00437 "AUTHREQ", 00438 "AUTHREP", 00439 "INVAL ", 00440 "LAGRQ ", 00441 "LAGRP ", 00442 "REGREQ ", 00443 "REGAUTH", 00444 "REGACK ", 00445 "REGREJ ", 00446 "REGREL ", 00447 "VNAK ", 00448 "DPREQ ", 00449 "DPREP ", 00450 "DIAL ", 00451 "TXREQ ", 00452 "TXCNT ", 00453 "TXACC ", 00454 "TXREADY", 00455 "TXREL ", 00456 "TXREJ ", 00457 "QUELCH ", 00458 "UNQULCH", 00459 "POKE ", 00460 "PAGE ", 00461 "MWI ", 00462 "UNSPRTD", 00463 "TRANSFR", 00464 "PROVISN", 00465 "FWDWNLD", 00466 "FWDATA ", 00467 "TXMEDIA" 00468 }; 00469 const char *cmds[] = { 00470 "(0?)", 00471 "HANGUP ", 00472 "RING ", 00473 "RINGING", 00474 "ANSWER ", 00475 "BUSY ", 00476 "TKOFFHK", 00477 "OFFHOOK", 00478 "CONGSTN", 00479 "FLASH ", 00480 "WINK ", 00481 "OPTION ", 00482 "RDKEY ", 00483 "RDUNKEY", 00484 "PROGRES", 00485 "PROCDNG", 00486 "HOLD ", 00487 "UNHOLD ", 00488 "VIDUPDT", }; 00489 struct ast_iax2_full_hdr *fh; 00490 char retries[20]; 00491 char class2[20]; 00492 char subclass2[20]; 00493 const char *class; 00494 const char *subclass; 00495 char *dir; 00496 char tmp[512]; 00497 00498 switch(rx) { 00499 case 0: 00500 dir = "Tx"; 00501 break; 00502 case 2: 00503 dir = "TE"; 00504 break; 00505 case 3: 00506 dir = "RD"; 00507 break; 00508 default: 00509 dir = "Rx"; 00510 break; 00511 } 00512 if (f) { 00513 fh = f->data; 00514 snprintf(retries, sizeof(retries), "%03d", f->retries); 00515 } else { 00516 fh = fhi; 00517 if (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) 00518 strcpy(retries, "Yes"); 00519 else 00520 strcpy(retries, " No"); 00521 } 00522 if (!(ntohs(fh->scallno) & IAX_FLAG_FULL)) { 00523 /* Don't mess with mini-frames */ 00524 return; 00525 } 00526 if (fh->type >= ARRAY_LEN(framelist)) { 00527 snprintf(class2, sizeof(class2), "(%d?)", fh->type); 00528 class = class2; 00529 } else { 00530 class = framelist[(int)fh->type]; 00531 } 00532 if (fh->type == AST_FRAME_DTMF_BEGIN || fh->type == AST_FRAME_DTMF_END) { 00533 sprintf(subclass2, "%c", fh->csub); 00534 subclass = subclass2; 00535 } else if (fh->type == AST_FRAME_IAX) { 00536 if (fh->csub >= (int)sizeof(iaxs)/(int)sizeof(iaxs[0])) { 00537 snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub); 00538 subclass = subclass2; 00539 } else { 00540 subclass = iaxs[(int)fh->csub]; 00541 } 00542 } else if (fh->type == AST_FRAME_CONTROL) { 00543 if (fh->csub >= (int)sizeof(cmds)/(int)sizeof(cmds[0])) { 00544 snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub); 00545 subclass = subclass2; 00546 } else { 00547 subclass = cmds[(int)fh->csub]; 00548 } 00549 } else { 00550 snprintf(subclass2, sizeof(subclass2), "%d", fh->csub); 00551 subclass = subclass2; 00552 } 00553 snprintf(tmp, sizeof(tmp), 00554 "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s Subclass: %s\n", 00555 dir, 00556 retries, fh->oseqno, fh->iseqno, class, subclass); 00557 outputf(tmp); 00558 snprintf(tmp, sizeof(tmp), 00559 " Timestamp: %05lums SCall: %5.5d DCall: %5.5d [%s:%d]\n", 00560 (unsigned long)ntohl(fh->ts), 00561 ntohs(fh->scallno) & ~IAX_FLAG_FULL, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, 00562 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 00563 outputf(tmp); 00564 if (fh->type == AST_FRAME_IAX) 00565 dump_ies(fh->iedata, datalen); 00566 }