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