#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) |
| struct 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 84 of file iax2-parser.h.
Referenced by iax_frame_free(), iax_frame_new(), and iaxfrdup2().
| #define DIRECTION_OUTGRESS 2 |
Definition at line 85 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 1134 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, iax_frames::list, and iax_frames::size.
Referenced by iax2_frame_free(), and network_thread().
01135 { 01136 #if !defined(LOW_MEMORY) 01137 struct iax_frames *iax_frames = NULL; 01138 #endif 01139 01140 /* Note: does not remove from scheduler! */ 01141 if (fr->direction == DIRECTION_INGRESS) 01142 ast_atomic_fetchadd_int(&iframes, -1); 01143 else if (fr->direction == DIRECTION_OUTGRESS) 01144 ast_atomic_fetchadd_int(&oframes, -1); 01145 else { 01146 errorf("Attempt to double free frame detected\n"); 01147 return; 01148 } 01149 ast_atomic_fetchadd_int(&frames, -1); 01150 01151 #if !defined(LOW_MEMORY) 01152 if (!fr->cacheable || !(iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) { 01153 ast_free(fr); 01154 return; 01155 } 01156 01157 if (iax_frames->size < FRAME_CACHE_MAX_SIZE) { 01158 fr->direction = 0; 01159 AST_LIST_INSERT_HEAD(&iax_frames->list, fr, list); 01160 iax_frames->size++; 01161 return; 01162 } 01163 #endif 01164 ast_free(fr); 01165 }
| struct iax_frame* iax_frame_new | ( | int | direction, | |
| int | datalen, | |||
| unsigned int | cacheable | |||
| ) | [read] |
Definition at line 1087 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(), iax_frame::cacheable, iax_frame::direction, DIRECTION_INGRESS, frame_cache, iax_frames::list, iax_frame::retrans, and iax_frames::size.
Referenced by iax2_send(), and iaxfrdup2().
01088 { 01089 struct iax_frame *fr = NULL; 01090 01091 #if !defined(LOW_MEMORY) 01092 struct iax_frames *iax_frames = NULL; 01093 01094 /* Attempt to get a frame from this thread's cache */ 01095 if ((iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) { 01096 AST_LIST_TRAVERSE_SAFE_BEGIN(&iax_frames->list, fr, list) { 01097 if (fr->afdatalen >= datalen) { 01098 size_t afdatalen = fr->afdatalen; 01099 AST_LIST_REMOVE_CURRENT(list); 01100 iax_frames->size--; 01101 memset(fr, 0, sizeof(*fr)); 01102 fr->afdatalen = afdatalen; 01103 break; 01104 } 01105 } 01106 AST_LIST_TRAVERSE_SAFE_END; 01107 } 01108 if (!fr) { 01109 if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen))) 01110 return NULL; 01111 fr->afdatalen = datalen; 01112 } 01113 #else 01114 if (!(fr = ast_calloc(1, sizeof(*fr) + datalen))) 01115 return NULL; 01116 fr->afdatalen = datalen; 01117 #endif 01118 01119 01120 fr->direction = direction; 01121 fr->retrans = -1; 01122 fr->cacheable = cacheable; 01123 01124 if (fr->direction == DIRECTION_INGRESS) 01125 ast_atomic_fetchadd_int(&iframes, 1); 01126 else 01127 ast_atomic_fetchadd_int(&oframes, 1); 01128 01129 ast_atomic_fetchadd_int(&frames, 1); 01130 01131 return fr; 01132 }
| 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_CALLTOKEN, 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 case IAX_COMMAND_CALLTOKEN: 00524 cmd = "CTOKEN "; 00525 break; 00526 } 00527 ast_copy_string(str, cmd, len); 00528 }
Definition at line 1056 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, 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().
01057 { 01058 fr->af.frametype = f->frametype; 01059 fr->af.subclass = f->subclass; 01060 fr->af.mallocd = 0; /* Our frame is static relative to the container */ 01061 fr->af.datalen = f->datalen; 01062 fr->af.samples = f->samples; 01063 fr->af.offset = AST_FRIENDLY_OFFSET; 01064 fr->af.src = f->src; 01065 fr->af.delivery.tv_sec = 0; 01066 fr->af.delivery.tv_usec = 0; 01067 fr->af.data = fr->afdata; 01068 fr->af.len = f->len; 01069 if (fr->af.datalen) { 01070 size_t copy_len = fr->af.datalen; 01071 if (copy_len > fr->afdatalen) { 01072 ast_log(LOG_ERROR, "Losing frame data because destination buffer size '%d' bytes not big enough for '%d' bytes in the frame\n", 01073 (int) fr->afdatalen, (int) fr->af.datalen); 01074 copy_len = fr->afdatalen; 01075 } 01076 #if __BYTE_ORDER == __LITTLE_ENDIAN 01077 /* We need to byte-swap slinear samples from network byte order */ 01078 if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass == AST_FORMAT_SLINEAR)) { 01079 /* 2 bytes / sample for SLINEAR */ 01080 ast_swapcopy_samples(fr->af.data, f->data, copy_len / 2); 01081 } else 01082 #endif 01083 memcpy(fr->af.data, f->data, copy_len); 01084 } 01085 }
| int iax_get_frames | ( | void | ) |
Definition at line 1180 of file iax2-parser.c.
Referenced by handle_cli_iax2_show_stats().
01180 { return frames; }
| int iax_get_iframes | ( | void | ) |
Definition at line 1181 of file iax2-parser.c.
Referenced by handle_cli_iax2_show_stats().
01181 { return iframes; }
| int iax_get_oframes | ( | void | ) |
Definition at line 1182 of file iax2-parser.c.
Referenced by handle_cli_iax2_show_stats().
01182 { return oframes; }
| const char* iax_ie2str | ( | int | ie | ) |
Definition at line 292 of file iax2-parser.c.
References ies, and iax2_ie::name.
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 686 of file iax2-parser.c.
References iax_ie_append_raw().
Referenced by iax2_call(), and iax_firmware_append().
00687 { 00688 return iax_ie_append_raw(ied, ie, NULL, 0); 00689 }
| int iax_ie_append_addr | ( | struct iax_ie_data * | ied, | |
| unsigned char | ie, | |||
| const struct sockaddr_in * | sin | |||
| ) |
Definition at line 657 of file iax2-parser.c.
References iax_ie_append_raw().
Referenced by iax2_start_transfer(), and update_registry().
00658 { 00659 return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in)); 00660 }
| int iax_ie_append_byte | ( | struct iax_ie_data * | ied, | |
| unsigned char | ie, | |||
| unsigned char | dat | |||
| ) |
Definition at line 681 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().
00682 { 00683 return iax_ie_append_raw(ied, ie, &dat, 1); 00684 }
| int iax_ie_append_int | ( | struct iax_ie_data * | ied, | |
| unsigned char | ie, | |||
| unsigned int | value | |||
| ) |
Definition at line 662 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().
00663 { 00664 unsigned int newval; 00665 newval = htonl(value); 00666 return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval)); 00667 }
| int iax_ie_append_raw | ( | struct iax_ie_data * | ied, | |
| unsigned char | ie, | |||
| const void * | data, | |||
| int | datalen | |||
| ) |
Definition at line 642 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().
00643 { 00644 char tmp[256]; 00645 if (datalen > ((int)sizeof(ied->buf) - ied->pos)) { 00646 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); 00647 errorf(tmp); 00648 return -1; 00649 } 00650 ied->buf[ied->pos++] = ie; 00651 ied->buf[ied->pos++] = datalen; 00652 memcpy(ied->buf + ied->pos, data, datalen); 00653 ied->pos += datalen; 00654 return 0; 00655 }
| int iax_ie_append_short | ( | struct iax_ie_data * | ied, | |
| unsigned char | ie, | |||
| unsigned short | value | |||
| ) |
Definition at line 669 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().
00670 { 00671 unsigned short newval; 00672 newval = htons(value); 00673 return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval)); 00674 }
| int iax_ie_append_str | ( | struct iax_ie_data * | ied, | |
| unsigned char | ie, | |||
| const char * | str | |||
| ) |
Definition at line 676 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().
00677 { 00678 return iax_ie_append_raw(ied, ie, str, strlen(str)); 00679 }
| int iax_parse_ies | ( | struct iax_ies * | ies, | |
| unsigned char * | data, | |||
| int | datalen | |||
| ) |
Definition at line 701 of file iax2-parser.c.
References iax_ies::adsicpe, iax_ies::apparent_addr, ast_copy_string(), ast_free, ast_str_create(), ast_str_set(), ast_variable_new(), iax_ies::authmethods, iax_ies::autoanswer, iax_ies::called_context, iax_ies::called_number, iax_ies::calling_ani, iax_ies::calling_name, iax_ies::calling_number, iax_ies::calling_pres, iax_ies::calling_tns, iax_ies::calling_ton, iax_ies::callno, iax_ies::calltoken, iax_ies::calltokendata, iax_ies::capability, iax_ies::cause, iax_ies::causecode, iax_ies::challenge, iax_ies::codec_prefs, iax_ies::datetime, iax_ies::devicetype, iax_ies::dnid, iax_ies::dpstatus, iax_ies::enckey, iax_ies::enckeylen, iax_ies::encmethods, errorf, ast_variable::file, iax_ies::firmwarever, iax_ies::format, iax_ies::fwdata, iax_ies::fwdatalen, iax_ies::fwdesc, get_unaligned_uint16(), get_unaligned_uint32(), iax_ie2str(), IAX_IE_ADSICPE, IAX_IE_APPARENT_ADDR, IAX_IE_AUTHMETHODS, IAX_IE_AUTOANSWER, IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CALLING_ANI, IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_CALLINGPRES, IAX_IE_CALLINGTNS, IAX_IE_CALLINGTON, IAX_IE_CALLNO, IAX_IE_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_OSPTOKEN, IAX_IE_PASSWORD, IAX_IE_PROVVER, IAX_IE_RDNIS, IAX_IE_REFRESH, IAX_IE_RR_DELAY, IAX_IE_RR_DROPPED, IAX_IE_RR_JITTER, IAX_IE_RR_LOSS, IAX_IE_RR_OOO, IAX_IE_RR_PKTS, IAX_IE_RSA_RESULT, IAX_IE_SAMPLINGRATE, IAX_IE_SERVICEIDENT, IAX_IE_TRANSFERID, IAX_IE_USERNAME, IAX_IE_VARIABLE, IAX_IE_VERSION, IAX_MAX_OSPBLOCK_NUM, IAX_RATE_8KHZ, iax_ies::iax_unknown, iax_ies::language, len(), iax_ies::md5_result, iax_ies::msgcount, iax_ies::musiconhold, ast_variable::name, ast_variable::next, iax_ies::ospblocklength, iax_ies::osptokenblock, outputf, iax_ies::password, iax_ies::provver, iax_ies::provverpres, iax_ies::rdnis, iax_ies::refresh, iax_ies::rr_delay, iax_ies::rr_dropped, iax_ies::rr_jitter, iax_ies::rr_loss, iax_ies::rr_ooo, iax_ies::rr_pkts, iax_ies::rsa_result, iax_ies::samprate, iax_ies::serviceident, ast_str::str, str, iax_ies::transferid, iax_ies::username, ast_variable::value, var, iax_ies::vars, and iax_ies::version.
Referenced by socket_process().
00702 { 00703 /* Parse data into information elements */ 00704 int len; 00705 int ie; 00706 char tmp[256], *tmp2; 00707 struct ast_variable *var, *var2, *prev; 00708 unsigned int count; 00709 memset(ies, 0, (int)sizeof(struct iax_ies)); 00710 ies->msgcount = -1; 00711 ies->firmwarever = -1; 00712 ies->calling_ton = -1; 00713 ies->calling_tns = -1; 00714 ies->calling_pres = -1; 00715 ies->samprate = IAX_RATE_8KHZ; 00716 while(datalen >= 2) { 00717 ie = data[0]; 00718 len = data[1]; 00719 if (len > datalen - 2) { 00720 errorf("Information element length exceeds message size\n"); 00721 return -1; 00722 } 00723 switch(ie) { 00724 case IAX_IE_CALLED_NUMBER: 00725 ies->called_number = (char *)data + 2; 00726 break; 00727 case IAX_IE_CALLING_NUMBER: 00728 ies->calling_number = (char *)data + 2; 00729 break; 00730 case IAX_IE_CALLING_ANI: 00731 ies->calling_ani = (char *)data + 2; 00732 break; 00733 case IAX_IE_CALLING_NAME: 00734 ies->calling_name = (char *)data + 2; 00735 break; 00736 case IAX_IE_CALLED_CONTEXT: 00737 ies->called_context = (char *)data + 2; 00738 break; 00739 case IAX_IE_USERNAME: 00740 ies->username = (char *)data + 2; 00741 break; 00742 case IAX_IE_PASSWORD: 00743 ies->password = (char *)data + 2; 00744 break; 00745 case IAX_IE_CODEC_PREFS: 00746 ies->codec_prefs = (char *)data + 2; 00747 break; 00748 case IAX_IE_CAPABILITY: 00749 if (len != (int)sizeof(unsigned int)) { 00750 snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00751 errorf(tmp); 00752 } else 00753 ies->capability = ntohl(get_unaligned_uint32(data + 2)); 00754 break; 00755 case IAX_IE_FORMAT: 00756 if (len != (int)sizeof(unsigned int)) { 00757 snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00758 errorf(tmp); 00759 } else 00760 ies->format = ntohl(get_unaligned_uint32(data + 2)); 00761 break; 00762 case IAX_IE_LANGUAGE: 00763 ies->language = (char *)data + 2; 00764 break; 00765 case IAX_IE_VERSION: 00766 if (len != (int)sizeof(unsigned short)) { 00767 snprintf(tmp, (int)sizeof(tmp), "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00768 errorf(tmp); 00769 } else 00770 ies->version = ntohs(get_unaligned_uint16(data + 2)); 00771 break; 00772 case IAX_IE_ADSICPE: 00773 if (len != (int)sizeof(unsigned short)) { 00774 snprintf(tmp, (int)sizeof(tmp), "Expecting adsicpe to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00775 errorf(tmp); 00776 } else 00777 ies->adsicpe = ntohs(get_unaligned_uint16(data + 2)); 00778 break; 00779 case IAX_IE_SAMPLINGRATE: 00780 if (len != (int)sizeof(unsigned short)) { 00781 snprintf(tmp, (int)sizeof(tmp), "Expecting samplingrate to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00782 errorf(tmp); 00783 } else 00784 ies->samprate = ntohs(get_unaligned_uint16(data + 2)); 00785 break; 00786 case IAX_IE_DNID: 00787 ies->dnid = (char *)data + 2; 00788 break; 00789 case IAX_IE_RDNIS: 00790 ies->rdnis = (char *)data + 2; 00791 break; 00792 case IAX_IE_AUTHMETHODS: 00793 if (len != (int)sizeof(unsigned short)) { 00794 snprintf(tmp, (int)sizeof(tmp), "Expecting authmethods to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00795 errorf(tmp); 00796 } else 00797 ies->authmethods = ntohs(get_unaligned_uint16(data + 2)); 00798 break; 00799 case IAX_IE_ENCRYPTION: 00800 if (len != (int)sizeof(unsigned short)) { 00801 snprintf(tmp, (int)sizeof(tmp), "Expecting encryption to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00802 errorf(tmp); 00803 } else 00804 ies->encmethods = ntohs(get_unaligned_uint16(data + 2)); 00805 break; 00806 case IAX_IE_CHALLENGE: 00807 ies->challenge = (char *)data + 2; 00808 break; 00809 case IAX_IE_MD5_RESULT: 00810 ies->md5_result = (char *)data + 2; 00811 break; 00812 case IAX_IE_RSA_RESULT: 00813 ies->rsa_result = (char *)data + 2; 00814 break; 00815 case IAX_IE_APPARENT_ADDR: 00816 ies->apparent_addr = ((struct sockaddr_in *)(data + 2)); 00817 break; 00818 case IAX_IE_REFRESH: 00819 if (len != (int)sizeof(unsigned short)) { 00820 snprintf(tmp, (int)sizeof(tmp), "Expecting refresh to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00821 errorf(tmp); 00822 } else 00823 ies->refresh = ntohs(get_unaligned_uint16(data + 2)); 00824 break; 00825 case IAX_IE_DPSTATUS: 00826 if (len != (int)sizeof(unsigned short)) { 00827 snprintf(tmp, (int)sizeof(tmp), "Expecting dpstatus to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00828 errorf(tmp); 00829 } else 00830 ies->dpstatus = ntohs(get_unaligned_uint16(data + 2)); 00831 break; 00832 case IAX_IE_CALLNO: 00833 if (len != (int)sizeof(unsigned short)) { 00834 snprintf(tmp, (int)sizeof(tmp), "Expecting callno to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00835 errorf(tmp); 00836 } else 00837 ies->callno = ntohs(get_unaligned_uint16(data + 2)); 00838 break; 00839 case IAX_IE_CAUSE: 00840 ies->cause = (char *)data + 2; 00841 break; 00842 case IAX_IE_CAUSECODE: 00843 if (len != 1) { 00844 snprintf(tmp, (int)sizeof(tmp), "Expecting causecode to be single byte but was %d\n", len); 00845 errorf(tmp); 00846 } else { 00847 ies->causecode = data[2]; 00848 } 00849 break; 00850 case IAX_IE_IAX_UNKNOWN: 00851 if (len == 1) 00852 ies->iax_unknown = data[2]; 00853 else { 00854 snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len); 00855 errorf(tmp); 00856 } 00857 break; 00858 case IAX_IE_MSGCOUNT: 00859 if (len != (int)sizeof(unsigned short)) { 00860 snprintf(tmp, (int)sizeof(tmp), "Expecting msgcount to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00861 errorf(tmp); 00862 } else 00863 ies->msgcount = ntohs(get_unaligned_uint16(data + 2)); 00864 break; 00865 case IAX_IE_AUTOANSWER: 00866 ies->autoanswer = 1; 00867 break; 00868 case IAX_IE_MUSICONHOLD: 00869 ies->musiconhold = 1; 00870 break; 00871 case IAX_IE_TRANSFERID: 00872 if (len != (int)sizeof(unsigned int)) { 00873 snprintf(tmp, (int)sizeof(tmp), "Expecting transferid to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00874 errorf(tmp); 00875 } else 00876 ies->transferid = ntohl(get_unaligned_uint32(data + 2)); 00877 break; 00878 case IAX_IE_DATETIME: 00879 if (len != (int)sizeof(unsigned int)) { 00880 snprintf(tmp, (int)sizeof(tmp), "Expecting date/time to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00881 errorf(tmp); 00882 } else 00883 ies->datetime = ntohl(get_unaligned_uint32(data + 2)); 00884 break; 00885 case IAX_IE_FIRMWAREVER: 00886 if (len != (int)sizeof(unsigned short)) { 00887 snprintf(tmp, (int)sizeof(tmp), "Expecting firmwarever to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00888 errorf(tmp); 00889 } else 00890 ies->firmwarever = ntohs(get_unaligned_uint16(data + 2)); 00891 break; 00892 case IAX_IE_DEVICETYPE: 00893 ies->devicetype = (char *)data + 2; 00894 break; 00895 case IAX_IE_SERVICEIDENT: 00896 ies->serviceident = (char *)data + 2; 00897 break; 00898 case IAX_IE_FWBLOCKDESC: 00899 if (len != (int)sizeof(unsigned int)) { 00900 snprintf(tmp, (int)sizeof(tmp), "Expected block desc to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00901 errorf(tmp); 00902 } else 00903 ies->fwdesc = ntohl(get_unaligned_uint32(data + 2)); 00904 break; 00905 case IAX_IE_FWBLOCKDATA: 00906 ies->fwdata = data + 2; 00907 ies->fwdatalen = len; 00908 break; 00909 case IAX_IE_ENCKEY: 00910 ies->enckey = data + 2; 00911 ies->enckeylen = len; 00912 break; 00913 case IAX_IE_PROVVER: 00914 if (len != (int)sizeof(unsigned int)) { 00915 snprintf(tmp, (int)sizeof(tmp), "Expected provisioning version to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00916 errorf(tmp); 00917 } else { 00918 ies->provverpres = 1; 00919 ies->provver = ntohl(get_unaligned_uint32(data + 2)); 00920 } 00921 break; 00922 case IAX_IE_CALLINGPRES: 00923 if (len == 1) 00924 ies->calling_pres = data[2]; 00925 else { 00926 snprintf(tmp, (int)sizeof(tmp), "Expected single byte callingpres, but was %d long\n", len); 00927 errorf(tmp); 00928 } 00929 break; 00930 case IAX_IE_CALLINGTON: 00931 if (len == 1) 00932 ies->calling_ton = data[2]; 00933 else { 00934 snprintf(tmp, (int)sizeof(tmp), "Expected single byte callington, but was %d long\n", len); 00935 errorf(tmp); 00936 } 00937 break; 00938 case IAX_IE_CALLINGTNS: 00939 if (len != (int)sizeof(unsigned short)) { 00940 snprintf(tmp, (int)sizeof(tmp), "Expecting callingtns to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00941 errorf(tmp); 00942 } else 00943 ies->calling_tns = ntohs(get_unaligned_uint16(data + 2)); 00944 break; 00945 case IAX_IE_RR_JITTER: 00946 if (len != (int)sizeof(unsigned int)) { 00947 snprintf(tmp, (int)sizeof(tmp), "Expected jitter rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00948 errorf(tmp); 00949 } else { 00950 ies->rr_jitter = ntohl(get_unaligned_uint32(data + 2)); 00951 } 00952 break; 00953 case IAX_IE_RR_LOSS: 00954 if (len != (int)sizeof(unsigned int)) { 00955 snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00956 errorf(tmp); 00957 } else { 00958 ies->rr_loss = ntohl(get_unaligned_uint32(data + 2)); 00959 } 00960 break; 00961 case IAX_IE_RR_PKTS: 00962 if (len != (int)sizeof(unsigned int)) { 00963 snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00964 errorf(tmp); 00965 } else { 00966 ies->rr_pkts = ntohl(get_unaligned_uint32(data + 2)); 00967 } 00968 break; 00969 case IAX_IE_RR_DELAY: 00970 if (len != (int)sizeof(unsigned short)) { 00971 snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00972 errorf(tmp); 00973 } else { 00974 ies->rr_delay = ntohs(get_unaligned_uint16(data + 2)); 00975 } 00976 break; 00977 case IAX_IE_RR_DROPPED: 00978 if (len != (int)sizeof(unsigned int)) { 00979 snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00980 errorf(tmp); 00981 } else { 00982 ies->rr_dropped = ntohl(get_unaligned_uint32(data + 2)); 00983 } 00984 break; 00985 case IAX_IE_RR_OOO: 00986 if (len != (int)sizeof(unsigned int)) { 00987 snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00988 errorf(tmp); 00989 } else { 00990 ies->rr_ooo = ntohl(get_unaligned_uint32(data + 2)); 00991 } 00992 break; 00993 case IAX_IE_VARIABLE: 00994 ast_copy_string(tmp, (char *)data + 2, len + 1); 00995 tmp2 = strchr(tmp, '='); 00996 if (tmp2) 00997 *tmp2++ = '\0'; 00998 else 00999 tmp2 = ""; 01000 { 01001 struct ast_str *str = ast_str_create(16); 01002 /* Existing variable or new variable? */ 01003 for (var2 = ies->vars, prev = NULL; var2; prev = var2, var2 = var2->next) { 01004 if (strcmp(tmp, var2->name) == 0) { 01005 ast_str_set(&str, 0, "%s%s", var2->value, tmp2); 01006 var = ast_variable_new(tmp, str->str, var2->file); 01007 var->next = var2->next; 01008 if (prev) 01009 prev->next = var; 01010 else 01011 ies->vars = var; 01012 ast_free(var2); 01013 break; 01014 } 01015 } 01016 } 01017 if (!var2) { 01018 var = ast_variable_new(tmp, tmp2, ""); 01019 var->next = ies->vars; 01020 ies->vars = var; 01021 } 01022 break; 01023 case IAX_IE_OSPTOKEN: 01024 if ((count = data[2]) < IAX_MAX_OSPBLOCK_NUM) { 01025 ies->osptokenblock[count] = (char *)data + 2 + 1; 01026 ies->ospblocklength[count] = len - 1; 01027 } else { 01028 snprintf(tmp, (int)sizeof(tmp), "Expected OSP token block index to be 0~%d but was %d\n", IAX_MAX_OSPBLOCK_NUM - 1, count); 01029 errorf(tmp); 01030 } 01031 break; 01032 case IAX_IE_CALLTOKEN: 01033 if (len) { 01034 ies->calltokendata = (unsigned char *) data + 2; 01035 } 01036 ies->calltoken = 1; 01037 break; 01038 default: 01039 snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len); 01040 outputf(tmp); 01041 } 01042 /* Overwrite information element with 0, to null terminate previous portion */ 01043 data[0] = 0; 01044 datalen -= (len + 2); 01045 data += (len + 2); 01046 } 01047 /* Null-terminate last field */ 01048 *data = '\0'; 01049 if (datalen) { 01050 errorf("Invalid information element contents, strange boundary\n"); 01051 return -1; 01052 } 01053 return 0; 01054 }
| 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 530 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, iax_frame::data, ast_iax2_full_hdr::dcallno, dir, dump_ies(), 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, iax_frame::retries, 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().
00531 { 00532 const char *frames[] = { 00533 "(0?)", 00534 "DTMF_E ", 00535 "VOICE ", 00536 "VIDEO ", 00537 "CONTROL", 00538 "NULL ", 00539 "IAX ", 00540 "TEXT ", 00541 "IMAGE ", 00542 "HTML ", 00543 "CNG ", 00544 "MODEM ", 00545 "DTMF_B ", 00546 }; 00547 const char *cmds[] = { 00548 "(0?)", 00549 "HANGUP ", 00550 "RING ", 00551 "RINGING", 00552 "ANSWER ", 00553 "BUSY ", 00554 "TKOFFHK", 00555 "OFFHOOK", 00556 "CONGSTN", 00557 "FLASH ", 00558 "WINK ", 00559 "OPTION ", 00560 "RDKEY ", 00561 "RDUNKEY", 00562 "PROGRES", 00563 "PROCDNG", 00564 "HOLD ", 00565 "UNHOLD ", 00566 "VIDUPDT", }; 00567 struct ast_iax2_full_hdr *fh; 00568 char retries[20]; 00569 char class2[20]; 00570 char subclass2[20]; 00571 const char *class; 00572 const char *subclass; 00573 char *dir; 00574 char tmp[512]; 00575 00576 switch(rx) { 00577 case 0: 00578 dir = "Tx"; 00579 break; 00580 case 2: 00581 dir = "TE"; 00582 break; 00583 case 3: 00584 dir = "RD"; 00585 break; 00586 default: 00587 dir = "Rx"; 00588 break; 00589 } 00590 if (f) { 00591 fh = f->data; 00592 snprintf(retries, sizeof(retries), "%03d", f->retries); 00593 } else { 00594 fh = fhi; 00595 if (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) 00596 strcpy(retries, "Yes"); 00597 else 00598 strcpy(retries, " No"); 00599 } 00600 if (!(ntohs(fh->scallno) & IAX_FLAG_FULL)) { 00601 /* Don't mess with mini-frames */ 00602 return; 00603 } 00604 if (fh->type >= (int)sizeof(frames)/(int)sizeof(frames[0])) { 00605 snprintf(class2, sizeof(class2), "(%d?)", fh->type); 00606 class = class2; 00607 } else { 00608 class = frames[(int)fh->type]; 00609 } 00610 if (fh->type == AST_FRAME_DTMF_BEGIN || fh->type == AST_FRAME_DTMF_END) { 00611 sprintf(subclass2, "%c", fh->csub); 00612 subclass = subclass2; 00613 } else if (fh->type == AST_FRAME_IAX) { 00614 iax_frame_subclass2str((int)fh->csub, subclass2, sizeof(subclass2)); 00615 subclass = subclass2; 00616 } else if (fh->type == AST_FRAME_CONTROL) { 00617 if (fh->csub >= (int)sizeof(cmds)/(int)sizeof(cmds[0])) { 00618 snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub); 00619 subclass = subclass2; 00620 } else { 00621 subclass = cmds[(int)fh->csub]; 00622 } 00623 } else { 00624 snprintf(subclass2, sizeof(subclass2), "%d", fh->csub); 00625 subclass = subclass2; 00626 } 00627 snprintf(tmp, sizeof(tmp), 00628 "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s Subclass: %s\n", 00629 dir, 00630 retries, fh->oseqno, fh->iseqno, class, subclass); 00631 outputf(tmp); 00632 snprintf(tmp, sizeof(tmp), 00633 " Timestamp: %05lums SCall: %5.5d DCall: %5.5d [%s:%d]\n", 00634 (unsigned long)ntohl(fh->ts), 00635 ntohs(fh->scallno) & ~IAX_FLAG_FULL, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, 00636 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 00637 outputf(tmp); 00638 if (fh->type == AST_FRAME_IAX) 00639 dump_ies(fh->iedata, datalen); 00640 }
1.5.6