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