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