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