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