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