Implementation of the IAX2 protocol. More...
#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) |
Implementation of the IAX2 protocol.
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 1168 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, iax_frames::list, and iax_frames::size.
Referenced by iax2_frame_free(), and network_thread().
01169 { 01170 #if !defined(LOW_MEMORY) 01171 struct iax_frames *iax_frames = NULL; 01172 #endif 01173 01174 /* Note: does not remove from scheduler! */ 01175 if (fr->direction == DIRECTION_INGRESS) 01176 ast_atomic_fetchadd_int(&iframes, -1); 01177 else if (fr->direction == DIRECTION_OUTGRESS) 01178 ast_atomic_fetchadd_int(&oframes, -1); 01179 else { 01180 errorf("Attempt to double free frame detected\n"); 01181 return; 01182 } 01183 ast_atomic_fetchadd_int(&frames, -1); 01184 01185 #if !defined(LOW_MEMORY) 01186 if (!fr->cacheable || !(iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) { 01187 ast_free(fr); 01188 return; 01189 } 01190 01191 if (iax_frames->size < FRAME_CACHE_MAX_SIZE) { 01192 fr->direction = 0; 01193 /* Pseudo-sort: keep smaller frames at the top of the list. This should 01194 * increase the chance that we pick the smallest applicable frame for use. */ 01195 if (AST_LIST_FIRST(&iax_frames->list) && AST_LIST_FIRST(&iax_frames->list)->afdatalen < fr->afdatalen) { 01196 AST_LIST_INSERT_TAIL(&iax_frames->list, fr, list); 01197 } else { 01198 AST_LIST_INSERT_HEAD(&iax_frames->list, fr, list); 01199 } 01200 iax_frames->size++; 01201 return; 01202 } 01203 #endif 01204 ast_free(fr); 01205 }
| struct iax_frame* iax_frame_new | ( | int | direction, | |
| int | datalen, | |||
| unsigned int | cacheable | |||
| ) | [read] |
Definition at line 1110 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(), iax_frame::cacheable, iax_frame::direction, DIRECTION_INGRESS, frame_cache, FRAME_CACHE_MAX_SIZE, iax_frame::list, iax_frames::list, iax_frame::retrans, and iax_frames::size.
Referenced by iax2_send(), and iaxfrdup2().
01111 { 01112 struct iax_frame *fr = NULL; 01113 01114 #if !defined(LOW_MEMORY) 01115 struct iax_frames *iax_frames = NULL; 01116 struct iax_frame *smallest = NULL; 01117 01118 /* Attempt to get a frame from this thread's cache */ 01119 if ((iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) { 01120 smallest = AST_LIST_FIRST(&iax_frames->list); 01121 AST_LIST_TRAVERSE_SAFE_BEGIN(&iax_frames->list, fr, list) { 01122 if (fr->afdatalen >= datalen) { 01123 size_t afdatalen = fr->afdatalen; 01124 AST_LIST_REMOVE_CURRENT(list); 01125 iax_frames->size--; 01126 memset(fr, 0, sizeof(*fr)); 01127 fr->afdatalen = afdatalen; 01128 break; 01129 } else if (smallest->afdatalen > fr->afdatalen) { 01130 smallest = fr; 01131 } 01132 } 01133 AST_LIST_TRAVERSE_SAFE_END; 01134 } 01135 if (!fr) { 01136 if (iax_frames->size >= FRAME_CACHE_MAX_SIZE && smallest) { 01137 /* Make useless cache into something more useful */ 01138 AST_LIST_REMOVE(&iax_frames->list, smallest, list); 01139 if (!(fr = ast_realloc(smallest, sizeof(*fr) + datalen))) { 01140 AST_LIST_INSERT_TAIL(&iax_frames->list, smallest, list); 01141 return NULL; 01142 } 01143 } else if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen))) 01144 return NULL; 01145 fr->afdatalen = datalen; 01146 } 01147 #else 01148 if (!(fr = ast_calloc(1, sizeof(*fr) + datalen))) 01149 return NULL; 01150 fr->afdatalen = datalen; 01151 #endif 01152 01153 01154 fr->direction = direction; 01155 fr->retrans = -1; 01156 fr->cacheable = cacheable; 01157 01158 if (fr->direction == DIRECTION_INGRESS) 01159 ast_atomic_fetchadd_int(&iframes, 1); 01160 else 01161 ast_atomic_fetchadd_int(&oframes, 1); 01162 01163 ast_atomic_fetchadd_int(&frames, 1); 01164 01165 return fr; 01166 }
| 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 1079 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::ptr, ast_frame::samples, ast_frame::src, and ast_frame::subclass.
Referenced by iax2_send(), iaxfrdup2(), socket_process(), and socket_process_meta().
01080 { 01081 fr->af.frametype = f->frametype; 01082 fr->af.subclass = f->subclass; 01083 fr->af.mallocd = 0; /* Our frame is static relative to the container */ 01084 fr->af.datalen = f->datalen; 01085 fr->af.samples = f->samples; 01086 fr->af.offset = AST_FRIENDLY_OFFSET; 01087 fr->af.src = f->src; 01088 fr->af.delivery.tv_sec = 0; 01089 fr->af.delivery.tv_usec = 0; 01090 fr->af.data.ptr = fr->afdata; 01091 fr->af.len = f->len; 01092 if (fr->af.datalen) { 01093 size_t copy_len = fr->af.datalen; 01094 if (copy_len > fr->afdatalen) { 01095 ast_log(LOG_ERROR, "Losing frame data because destination buffer size '%d' bytes not big enough for '%d' bytes in the frame\n", 01096 (int) fr->afdatalen, (int) fr->af.datalen); 01097 copy_len = fr->afdatalen; 01098 } 01099 #if __BYTE_ORDER == __LITTLE_ENDIAN 01100 /* We need to byte-swap slinear samples from network byte order */ 01101 if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass == AST_FORMAT_SLINEAR)) { 01102 /* 2 bytes / sample for SLINEAR */ 01103 ast_swapcopy_samples(fr->af.data.ptr, f->data.ptr, copy_len / 2); 01104 } else 01105 #endif 01106 memcpy(fr->af.data.ptr, f->data.ptr, copy_len); 01107 } 01108 }
| int iax_get_frames | ( | void | ) |
Definition at line 1220 of file iax2-parser.c.
Referenced by handle_cli_iax2_show_stats().
01220 { return frames; }
| int iax_get_iframes | ( | void | ) |
Definition at line 1221 of file iax2-parser.c.
Referenced by handle_cli_iax2_show_stats().
01221 { return iframes; }
| int iax_get_oframes | ( | void | ) |
Definition at line 1222 of file iax2-parser.c.
Referenced by handle_cli_iax2_show_stats().
01222 { 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().
| int iax_ie_append | ( | struct iax_ie_data * | ied, | |
| unsigned char | ie | |||
| ) |
Definition at line 702 of file iax2-parser.c.
References iax_ie_append_raw().
Referenced by iax2_call(), and iax_firmware_append().
00703 { 00704 return iax_ie_append_raw(ied, ie, NULL, 0); 00705 }
| int iax_ie_append_addr | ( | struct iax_ie_data * | ied, | |
| unsigned char | ie, | |||
| const struct sockaddr_in * | sin | |||
| ) |
Definition at line 673 of file iax2-parser.c.
References iax_ie_append_raw().
Referenced by iax2_start_transfer(), and update_registry().
00674 { 00675 return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in)); 00676 }
| int iax_ie_append_byte | ( | struct iax_ie_data * | ied, | |
| unsigned char | ie, | |||
| unsigned char | dat | |||
| ) |
Definition at line 697 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().
00698 { 00699 return iax_ie_append_raw(ied, ie, &dat, 1); 00700 }
| int iax_ie_append_int | ( | struct iax_ie_data * | ied, | |
| unsigned char | ie, | |||
| unsigned int | value | |||
| ) |
Definition at line 678 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().
00679 { 00680 unsigned int newval; 00681 newval = htonl(value); 00682 return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval)); 00683 }
| int iax_ie_append_raw | ( | struct iax_ie_data * | ied, | |
| unsigned char | ie, | |||
| const void * | data, | |||
| int | datalen | |||
| ) |
Definition at line 658 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().
00659 { 00660 char tmp[256]; 00661 if (datalen > ((int)sizeof(ied->buf) - ied->pos)) { 00662 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); 00663 errorf(tmp); 00664 return -1; 00665 } 00666 ied->buf[ied->pos++] = ie; 00667 ied->buf[ied->pos++] = datalen; 00668 memcpy(ied->buf + ied->pos, data, datalen); 00669 ied->pos += datalen; 00670 return 0; 00671 }
| int iax_ie_append_short | ( | struct iax_ie_data * | ied, | |
| unsigned char | ie, | |||
| unsigned short | value | |||
| ) |
Definition at line 685 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().
00686 { 00687 unsigned short newval; 00688 newval = htons(value); 00689 return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval)); 00690 }
| int iax_ie_append_str | ( | struct iax_ie_data * | ied, | |
| unsigned char | ie, | |||
| const char * | str | |||
| ) |
Definition at line 692 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().
00693 { 00694 return iax_ie_append_raw(ied, ie, str, strlen(str)); 00695 }
| int iax_parse_ies | ( | struct iax_ies * | ies, | |
| unsigned char * | data, | |||
| int | datalen | |||
| ) |
Definition at line 717 of file iax2-parser.c.
References iax_ies::adsicpe, iax_ies::apparent_addr, ast_copy_string(), ast_free, ast_str_buffer(), 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().
00718 { 00719 /* Parse data into information elements */ 00720 int len; 00721 int ie; 00722 char tmp[256], *tmp2; 00723 struct ast_variable *var, *var2, *prev; 00724 unsigned int count; 00725 memset(ies, 0, (int)sizeof(struct iax_ies)); 00726 ies->msgcount = -1; 00727 ies->firmwarever = -1; 00728 ies->calling_ton = -1; 00729 ies->calling_tns = -1; 00730 ies->calling_pres = -1; 00731 ies->samprate = IAX_RATE_8KHZ; 00732 while(datalen >= 2) { 00733 ie = data[0]; 00734 len = data[1]; 00735 if (len > datalen - 2) { 00736 errorf("Information element length exceeds message size\n"); 00737 return -1; 00738 } 00739 switch(ie) { 00740 case IAX_IE_CALLED_NUMBER: 00741 ies->called_number = (char *)data + 2; 00742 break; 00743 case IAX_IE_CALLING_NUMBER: 00744 ies->calling_number = (char *)data + 2; 00745 break; 00746 case IAX_IE_CALLING_ANI: 00747 ies->calling_ani = (char *)data + 2; 00748 break; 00749 case IAX_IE_CALLING_NAME: 00750 ies->calling_name = (char *)data + 2; 00751 break; 00752 case IAX_IE_CALLED_CONTEXT: 00753 ies->called_context = (char *)data + 2; 00754 break; 00755 case IAX_IE_USERNAME: 00756 ies->username = (char *)data + 2; 00757 break; 00758 case IAX_IE_PASSWORD: 00759 ies->password = (char *)data + 2; 00760 break; 00761 case IAX_IE_CODEC_PREFS: 00762 ies->codec_prefs = (char *)data + 2; 00763 break; 00764 case IAX_IE_CAPABILITY: 00765 if (len != (int)sizeof(unsigned int)) { 00766 snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00767 errorf(tmp); 00768 } else 00769 ies->capability = ntohl(get_unaligned_uint32(data + 2)); 00770 break; 00771 case IAX_IE_FORMAT: 00772 if (len != (int)sizeof(unsigned int)) { 00773 snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00774 errorf(tmp); 00775 } else 00776 ies->format = ntohl(get_unaligned_uint32(data + 2)); 00777 break; 00778 case IAX_IE_LANGUAGE: 00779 ies->language = (char *)data + 2; 00780 break; 00781 case IAX_IE_VERSION: 00782 if (len != (int)sizeof(unsigned short)) { 00783 snprintf(tmp, (int)sizeof(tmp), "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00784 errorf(tmp); 00785 } else 00786 ies->version = ntohs(get_unaligned_uint16(data + 2)); 00787 break; 00788 case IAX_IE_ADSICPE: 00789 if (len != (int)sizeof(unsigned short)) { 00790 snprintf(tmp, (int)sizeof(tmp), "Expecting adsicpe to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00791 errorf(tmp); 00792 } else 00793 ies->adsicpe = ntohs(get_unaligned_uint16(data + 2)); 00794 break; 00795 case IAX_IE_SAMPLINGRATE: 00796 if (len != (int)sizeof(unsigned short)) { 00797 snprintf(tmp, (int)sizeof(tmp), "Expecting samplingrate to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00798 errorf(tmp); 00799 } else 00800 ies->samprate = ntohs(get_unaligned_uint16(data + 2)); 00801 break; 00802 case IAX_IE_DNID: 00803 ies->dnid = (char *)data + 2; 00804 break; 00805 case IAX_IE_RDNIS: 00806 ies->rdnis = (char *)data + 2; 00807 break; 00808 case IAX_IE_AUTHMETHODS: 00809 if (len != (int)sizeof(unsigned short)) { 00810 snprintf(tmp, (int)sizeof(tmp), "Expecting authmethods to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00811 errorf(tmp); 00812 } else 00813 ies->authmethods = ntohs(get_unaligned_uint16(data + 2)); 00814 break; 00815 case IAX_IE_ENCRYPTION: 00816 if (len != (int)sizeof(unsigned short)) { 00817 snprintf(tmp, (int)sizeof(tmp), "Expecting encryption to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00818 errorf(tmp); 00819 } else 00820 ies->encmethods = ntohs(get_unaligned_uint16(data + 2)); 00821 break; 00822 case IAX_IE_CHALLENGE: 00823 ies->challenge = (char *)data + 2; 00824 break; 00825 case IAX_IE_MD5_RESULT: 00826 ies->md5_result = (char *)data + 2; 00827 break; 00828 case IAX_IE_RSA_RESULT: 00829 ies->rsa_result = (char *)data + 2; 00830 break; 00831 case IAX_IE_APPARENT_ADDR: 00832 ies->apparent_addr = ((struct sockaddr_in *)(data + 2)); 00833 break; 00834 case IAX_IE_REFRESH: 00835 if (len != (int)sizeof(unsigned short)) { 00836 snprintf(tmp, (int)sizeof(tmp), "Expecting refresh to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00837 errorf(tmp); 00838 } else 00839 ies->refresh = ntohs(get_unaligned_uint16(data + 2)); 00840 break; 00841 case IAX_IE_DPSTATUS: 00842 if (len != (int)sizeof(unsigned short)) { 00843 snprintf(tmp, (int)sizeof(tmp), "Expecting dpstatus to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00844 errorf(tmp); 00845 } else 00846 ies->dpstatus = ntohs(get_unaligned_uint16(data + 2)); 00847 break; 00848 case IAX_IE_CALLNO: 00849 if (len != (int)sizeof(unsigned short)) { 00850 snprintf(tmp, (int)sizeof(tmp), "Expecting callno to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00851 errorf(tmp); 00852 } else 00853 ies->callno = ntohs(get_unaligned_uint16(data + 2)); 00854 break; 00855 case IAX_IE_CAUSE: 00856 ies->cause = (char *)data + 2; 00857 break; 00858 case IAX_IE_CAUSECODE: 00859 if (len != 1) { 00860 snprintf(tmp, (int)sizeof(tmp), "Expecting causecode to be single byte but was %d\n", len); 00861 errorf(tmp); 00862 } else { 00863 ies->causecode = data[2]; 00864 } 00865 break; 00866 case IAX_IE_IAX_UNKNOWN: 00867 if (len == 1) 00868 ies->iax_unknown = data[2]; 00869 else { 00870 snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len); 00871 errorf(tmp); 00872 } 00873 break; 00874 case IAX_IE_MSGCOUNT: 00875 if (len != (int)sizeof(unsigned short)) { 00876 snprintf(tmp, (int)sizeof(tmp), "Expecting msgcount to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00877 errorf(tmp); 00878 } else 00879 ies->msgcount = ntohs(get_unaligned_uint16(data + 2)); 00880 break; 00881 case IAX_IE_AUTOANSWER: 00882 ies->autoanswer = 1; 00883 break; 00884 case IAX_IE_MUSICONHOLD: 00885 ies->musiconhold = 1; 00886 break; 00887 case IAX_IE_TRANSFERID: 00888 if (len != (int)sizeof(unsigned int)) { 00889 snprintf(tmp, (int)sizeof(tmp), "Expecting transferid to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00890 errorf(tmp); 00891 } else 00892 ies->transferid = ntohl(get_unaligned_uint32(data + 2)); 00893 break; 00894 case IAX_IE_DATETIME: 00895 if (len != (int)sizeof(unsigned int)) { 00896 snprintf(tmp, (int)sizeof(tmp), "Expecting date/time to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00897 errorf(tmp); 00898 } else 00899 ies->datetime = ntohl(get_unaligned_uint32(data + 2)); 00900 break; 00901 case IAX_IE_FIRMWAREVER: 00902 if (len != (int)sizeof(unsigned short)) { 00903 snprintf(tmp, (int)sizeof(tmp), "Expecting firmwarever to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00904 errorf(tmp); 00905 } else 00906 ies->firmwarever = ntohs(get_unaligned_uint16(data + 2)); 00907 break; 00908 case IAX_IE_DEVICETYPE: 00909 ies->devicetype = (char *)data + 2; 00910 break; 00911 case IAX_IE_SERVICEIDENT: 00912 ies->serviceident = (char *)data + 2; 00913 break; 00914 case IAX_IE_FWBLOCKDESC: 00915 if (len != (int)sizeof(unsigned int)) { 00916 snprintf(tmp, (int)sizeof(tmp), "Expected block desc to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00917 errorf(tmp); 00918 } else 00919 ies->fwdesc = ntohl(get_unaligned_uint32(data + 2)); 00920 break; 00921 case IAX_IE_FWBLOCKDATA: 00922 ies->fwdata = data + 2; 00923 ies->fwdatalen = len; 00924 break; 00925 case IAX_IE_ENCKEY: 00926 ies->enckey = data + 2; 00927 ies->enckeylen = len; 00928 break; 00929 case IAX_IE_PROVVER: 00930 if (len != (int)sizeof(unsigned int)) { 00931 snprintf(tmp, (int)sizeof(tmp), "Expected provisioning version to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00932 errorf(tmp); 00933 } else { 00934 ies->provverpres = 1; 00935 ies->provver = ntohl(get_unaligned_uint32(data + 2)); 00936 } 00937 break; 00938 case IAX_IE_CALLINGPRES: 00939 if (len == 1) 00940 ies->calling_pres = data[2]; 00941 else { 00942 snprintf(tmp, (int)sizeof(tmp), "Expected single byte callingpres, but was %d long\n", len); 00943 errorf(tmp); 00944 } 00945 break; 00946 case IAX_IE_CALLINGTON: 00947 if (len == 1) 00948 ies->calling_ton = data[2]; 00949 else { 00950 snprintf(tmp, (int)sizeof(tmp), "Expected single byte callington, but was %d long\n", len); 00951 errorf(tmp); 00952 } 00953 break; 00954 case IAX_IE_CALLINGTNS: 00955 if (len != (int)sizeof(unsigned short)) { 00956 snprintf(tmp, (int)sizeof(tmp), "Expecting callingtns to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00957 errorf(tmp); 00958 } else 00959 ies->calling_tns = ntohs(get_unaligned_uint16(data + 2)); 00960 break; 00961 case IAX_IE_RR_JITTER: 00962 if (len != (int)sizeof(unsigned int)) { 00963 snprintf(tmp, (int)sizeof(tmp), "Expected jitter rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00964 errorf(tmp); 00965 } else { 00966 ies->rr_jitter = ntohl(get_unaligned_uint32(data + 2)); 00967 } 00968 break; 00969 case IAX_IE_RR_LOSS: 00970 if (len != (int)sizeof(unsigned int)) { 00971 snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00972 errorf(tmp); 00973 } else { 00974 ies->rr_loss = ntohl(get_unaligned_uint32(data + 2)); 00975 } 00976 break; 00977 case IAX_IE_RR_PKTS: 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_pkts = ntohl(get_unaligned_uint32(data + 2)); 00983 } 00984 break; 00985 case IAX_IE_RR_DELAY: 00986 if (len != (int)sizeof(unsigned short)) { 00987 snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00988 errorf(tmp); 00989 } else { 00990 ies->rr_delay = ntohs(get_unaligned_uint16(data + 2)); 00991 } 00992 break; 00993 case IAX_IE_RR_DROPPED: 00994 if (len != (int)sizeof(unsigned int)) { 00995 snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00996 errorf(tmp); 00997 } else { 00998 ies->rr_dropped = ntohl(get_unaligned_uint32(data + 2)); 00999 } 01000 break; 01001 case IAX_IE_RR_OOO: 01002 if (len != (int)sizeof(unsigned int)) { 01003 snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 01004 errorf(tmp); 01005 } else { 01006 ies->rr_ooo = ntohl(get_unaligned_uint32(data + 2)); 01007 } 01008 break; 01009 case IAX_IE_VARIABLE: 01010 ast_copy_string(tmp, (char *)data + 2, len + 1); 01011 tmp2 = strchr(tmp, '='); 01012 if (tmp2) 01013 *tmp2++ = '\0'; 01014 else 01015 tmp2 = ""; 01016 { 01017 struct ast_str *str = ast_str_create(16); 01018 /* Existing variable or new variable? */ 01019 for (var2 = ies->vars, prev = NULL; var2; prev = var2, var2 = var2->next) { 01020 if (strcmp(tmp, var2->name) == 0) { 01021 ast_str_set(&str, 0, "%s%s", var2->value, tmp2); 01022 var = ast_variable_new(tmp, ast_str_buffer(str), var2->file); 01023 var->next = var2->next; 01024 if (prev) { 01025 prev->next = var; 01026 } else { 01027 ies->vars = var; 01028 } 01029 snprintf(tmp, sizeof(tmp), "Assigned (%p)%s to (%p)%s\n", var->name, var->name, var->value, var->value); 01030 outputf(tmp); 01031 ast_free(var2); 01032 break; 01033 } 01034 } 01035 ast_free(str); 01036 } 01037 01038 if (!var2) { 01039 var = ast_variable_new(tmp, tmp2, ""); 01040 snprintf(tmp, sizeof(tmp), "Assigned (%p)%s to (%p)%s\n", var->name, var->name, var->value, var->value); 01041 outputf(tmp); 01042 var->next = ies->vars; 01043 ies->vars = var; 01044 } 01045 break; 01046 case IAX_IE_OSPTOKEN: 01047 if ((count = data[2]) < IAX_MAX_OSPBLOCK_NUM) { 01048 ies->osptokenblock[count] = (char *)data + 2 + 1; 01049 ies->ospblocklength[count] = len - 1; 01050 } else { 01051 snprintf(tmp, (int)sizeof(tmp), "Expected OSP token block index to be 0~%d but was %d\n", IAX_MAX_OSPBLOCK_NUM - 1, count); 01052 errorf(tmp); 01053 } 01054 break; 01055 case IAX_IE_CALLTOKEN: 01056 if (len) { 01057 ies->calltokendata = (unsigned char *) data + 2; 01058 } 01059 ies->calltoken = 1; 01060 break; 01061 default: 01062 snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len); 01063 outputf(tmp); 01064 } 01065 /* Overwrite information element with 0, to null terminate previous portion */ 01066 data[0] = 0; 01067 datalen -= (len + 2); 01068 data += (len + 2); 01069 } 01070 /* Null-terminate last field */ 01071 *data = '\0'; 01072 if (datalen) { 01073 errorf("Invalid information element contents, strange boundary\n"); 01074 return -1; 01075 } 01076 return 0; 01077 }
| 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, 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 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 "T38 ", 00581 "SRCUPDT", 00582 }; 00583 struct ast_iax2_full_hdr *fh; 00584 char retries[20]; 00585 char class2[20]; 00586 char subclass2[20]; 00587 const char *class; 00588 const char *subclass; 00589 char *dir; 00590 char tmp[512]; 00591 00592 switch(rx) { 00593 case 0: 00594 dir = "Tx"; 00595 break; 00596 case 2: 00597 dir = "TE"; 00598 break; 00599 case 3: 00600 dir = "RD"; 00601 break; 00602 default: 00603 dir = "Rx"; 00604 break; 00605 } 00606 if (f) { 00607 fh = f->data; 00608 snprintf(retries, sizeof(retries), "%03d", f->retries); 00609 } else { 00610 fh = fhi; 00611 if (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) 00612 strcpy(retries, "Yes"); 00613 else 00614 strcpy(retries, " No"); 00615 } 00616 if (!(ntohs(fh->scallno) & IAX_FLAG_FULL)) { 00617 /* Don't mess with mini-frames */ 00618 return; 00619 } 00620 if (fh->type >= ARRAY_LEN(framelist)) { 00621 snprintf(class2, sizeof(class2), "(%d?)", fh->type); 00622 class = class2; 00623 } else { 00624 class = framelist[(int)fh->type]; 00625 } 00626 if (fh->type == AST_FRAME_DTMF_BEGIN || fh->type == AST_FRAME_DTMF_END) { 00627 sprintf(subclass2, "%c", fh->csub); 00628 subclass = subclass2; 00629 } else if (fh->type == AST_FRAME_IAX) { 00630 iax_frame_subclass2str((int)fh->csub, subclass2, sizeof(subclass2)); 00631 subclass = subclass2; 00632 } else if (fh->type == AST_FRAME_CONTROL) { 00633 if (fh->csub >= ARRAY_LEN(cmds)) { 00634 snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub); 00635 subclass = subclass2; 00636 } else { 00637 subclass = cmds[(int)fh->csub]; 00638 } 00639 } else { 00640 snprintf(subclass2, sizeof(subclass2), "%d", fh->csub); 00641 subclass = subclass2; 00642 } 00643 snprintf(tmp, sizeof(tmp), 00644 "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s Subclass: %s\n", 00645 dir, 00646 retries, fh->oseqno, fh->iseqno, class, subclass); 00647 outputf(tmp); 00648 snprintf(tmp, sizeof(tmp), 00649 " Timestamp: %05lums SCall: %5.5d DCall: %5.5d [%s:%d]\n", 00650 (unsigned long)ntohl(fh->ts), 00651 ntohs(fh->scallno) & ~IAX_FLAG_FULL, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, 00652 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 00653 outputf(tmp); 00654 if (fh->type == AST_FRAME_IAX) 00655 dump_ies(fh->iedata, datalen); 00656 }
1.6.2