#include "asterisk.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "asterisk/frame.h"
#include "asterisk/utils.h"
#include "asterisk/unaligned.h"
#include "asterisk/config.h"
#include "asterisk/lock.h"
#include "asterisk/threadstorage.h"
#include "iax2.h"
#include "iax2-parser.h"
#include "iax2-provision.h"
Go to the source code of this file.
Data Structures | |
struct | iax2_ie |
struct | iax_frame_list |
This is just so iax_frames, a list head struct for holding a list of iax_frame structures, is defined. More... | |
struct | iax_frames |
Defines | |
#define | FRAME_CACHE_MAX_SIZE 20 |
Functions | |
static void | __init_frame_cache (void) |
A per-thread cache of iax_frame structures. | |
static void | dump_addr (char *output, int maxlen, void *value, int len) |
static void | dump_byte (char *output, int maxlen, void *value, int len) |
static void | dump_datetime (char *output, int maxlen, void *value, int len) |
static void | dump_ies (unsigned char *iedata, int len) |
static void | dump_int (char *output, int maxlen, void *value, int len) |
static void | dump_ipaddr (char *output, int maxlen, void *value, int len) |
static void | dump_prefs (char *output, int maxlen, void *value, int len) |
static void | dump_prov (char *output, int maxlen, void *value, int len) |
static void | dump_prov_flags (char *output, int maxlen, void *value, int len) |
static void | dump_prov_ies (char *output, int maxlen, unsigned char *iedata, int len) |
static void | dump_samprate (char *output, int maxlen, void *value, int len) |
static void | dump_short (char *output, int maxlen, void *value, int len) |
static void | dump_string (char *output, int maxlen, void *value, int len) |
static void | dump_string_hex (char *output, int maxlen, void *value, int len) |
static void | dump_versioned_codec (char *output, int maxlen, void *value, int len) |
static void | frame_cache_cleanup (void *data) |
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(*func)(const char *)) |
void | iax_set_output (void(*func)(const char *)) |
void | iax_showframe (struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen) |
static void | internalerror (const char *str) |
static void | internaloutput (const char *str) |
Variables | |
static void(*) | errorf (const char *str) = internalerror |
static struct ast_threadstorage | frame_cache = { .once = PTHREAD_ONCE_INIT , .key_init = __init_frame_cache , .custom_init = NULL , } |
static int | frames = 0 |
static int | iframes = 0 |
static struct iax2_ie | infoelts [] |
static int | oframes = 0 |
static void(*) | outputf (const char *str) = internaloutput |
static struct iax2_ie | prov_ies [] |
Definition in file iax2-parser.c.
#define FRAME_CACHE_MAX_SIZE 20 |
Definition at line 68 of file iax2-parser.c.
Referenced by __frame_free(), iax_frame_free(), and iax_frame_new().
static void __init_frame_cache | ( | void | ) | [static] |
static void dump_addr | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 84 of file iax2-parser.c.
References ast_copy_string(), and ast_inet_ntoa().
00085 { 00086 struct sockaddr_in sin; 00087 if (len == (int)sizeof(sin)) { 00088 memcpy(&sin, value, len); 00089 snprintf(output, maxlen, "IPV4 %s:%d", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 00090 } else { 00091 ast_copy_string(output, "Invalid Address", maxlen); 00092 } 00093 }
static void dump_byte | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 149 of file iax2-parser.c.
References ast_copy_string().
00150 { 00151 if (len == (int)sizeof(unsigned char)) 00152 snprintf(output, maxlen, "%d", *((unsigned char *)value)); 00153 else 00154 ast_copy_string(output, "Invalid BYTE", maxlen); 00155 }
static void dump_datetime | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 157 of file iax2-parser.c.
References ast_copy_string(), ast_strftime(), get_unaligned_uint32(), ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, and ast_tm::tm_year.
00158 { 00159 struct ast_tm tm; 00160 unsigned long val = (unsigned long) ntohl(get_unaligned_uint32(value)); 00161 if (len == (int)sizeof(unsigned int)) { 00162 tm.tm_sec = (val & 0x1f) << 1; 00163 tm.tm_min = (val >> 5) & 0x3f; 00164 tm.tm_hour = (val >> 11) & 0x1f; 00165 tm.tm_mday = (val >> 16) & 0x1f; 00166 tm.tm_mon = ((val >> 21) & 0x0f) - 1; 00167 tm.tm_year = ((val >> 25) & 0x7f) + 100; 00168 ast_strftime(output, maxlen, "%Y-%m-%d %T", &tm); 00169 } else 00170 ast_copy_string(output, "Invalid DATETIME format!", maxlen); 00171 }
static void dump_ies | ( | unsigned char * | iedata, | |
int | len | |||
) | [static] |
Definition at line 387 of file iax2-parser.c.
References ARRAY_LEN, iax2_ie::dump, iax2_ie::ie, infoelts, name, and outputf.
Referenced by dundi_showframe(), and iax_showframe().
00388 { 00389 int ielen; 00390 int ie; 00391 int x; 00392 int found; 00393 char interp[1024]; 00394 char tmp[1024]; 00395 if (len < 2) 00396 return; 00397 while(len > 2) { 00398 ie = iedata[0]; 00399 ielen = iedata[1]; 00400 if (ielen + 2> len) { 00401 snprintf(tmp, (int)sizeof(tmp), "Total IE length of %d bytes exceeds remaining frame length of %d bytes\n", ielen + 2, len); 00402 outputf(tmp); 00403 return; 00404 } 00405 found = 0; 00406 for (x = 0; x < ARRAY_LEN(infoelts); x++) { 00407 if (infoelts[x].ie == ie) { 00408 if (infoelts[x].dump) { 00409 infoelts[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen); 00410 snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", infoelts[x].name, interp); 00411 outputf(tmp); 00412 } else { 00413 if (ielen) 00414 snprintf(interp, (int)sizeof(interp), "%d bytes", ielen); 00415 else 00416 strcpy(interp, "Present"); 00417 snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", infoelts[x].name, interp); 00418 outputf(tmp); 00419 } 00420 found++; 00421 } 00422 } 00423 if (!found) { 00424 snprintf(tmp, (int)sizeof(tmp), " Unknown IE %03d : Present\n", ie); 00425 outputf(tmp); 00426 } 00427 iedata += (2 + ielen); 00428 len -= (2 + ielen); 00429 } 00430 outputf("\n"); 00431 }
static void dump_int | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 133 of file iax2-parser.c.
References ast_copy_string(), and get_unaligned_uint32().
00134 { 00135 if (len == (int)sizeof(unsigned int)) 00136 snprintf(output, maxlen, "%lu", (unsigned long)ntohl(get_unaligned_uint32(value))); 00137 else 00138 ast_copy_string(output, "Invalid INT", maxlen); 00139 }
static void dump_ipaddr | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 173 of file iax2-parser.c.
References ast_copy_string(), and ast_inet_ntoa().
00174 { 00175 struct sockaddr_in sin; 00176 if (len == (int)sizeof(unsigned int)) { 00177 memcpy(&sin.sin_addr, value, len); 00178 snprintf(output, maxlen, "%s", ast_inet_ntoa(sin.sin_addr)); 00179 } else 00180 ast_copy_string(output, "Invalid IPADDR", maxlen); 00181 }
static void dump_prefs | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 114 of file iax2-parser.c.
References ast_codec_pref_convert(), and ast_codec_pref_string().
00115 { 00116 struct ast_codec_pref pref; 00117 int total_len = 0; 00118 00119 maxlen--; 00120 total_len = maxlen; 00121 00122 if (maxlen > len) 00123 maxlen = len; 00124 00125 strncpy(output, value, maxlen); 00126 output[maxlen] = '\0'; 00127 00128 ast_codec_pref_convert(&pref, output, total_len, 0); 00129 memset(output,0,total_len); 00130 ast_codec_pref_string(&pref, output, total_len); 00131 }
static void dump_prov | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 237 of file iax2-parser.c.
References dump_prov_ies().
00238 { 00239 dump_prov_ies(output, maxlen, value, len); 00240 }
static void dump_prov_flags | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 184 of file iax2-parser.c.
References ast_copy_string(), get_unaligned_uint32(), and iax_provflags2str().
00185 { 00186 char buf[256] = ""; 00187 if (len == (int)sizeof(unsigned int)) 00188 snprintf(output, maxlen, "%lu (%s)", (unsigned long)ntohl(get_unaligned_uint32(value)), 00189 iax_provflags2str(buf, sizeof(buf), ntohl(get_unaligned_uint32(value)))); 00190 else 00191 ast_copy_string(output, "Invalid INT", maxlen); 00192 }
static void dump_prov_ies | ( | char * | output, | |
int | maxlen, | |||
unsigned char * | iedata, | |||
int | len | |||
) | [static] |
Definition at line 335 of file iax2-parser.c.
References ast_copy_string(), iax2_ie::dump, iax2_ie::ie, name, and prov_ies.
Referenced by dump_prov().
00336 { 00337 int ielen; 00338 int ie; 00339 int x; 00340 int found; 00341 char interp[80]; 00342 char tmp[256]; 00343 if (len < 2) 00344 return; 00345 strcpy(output, "\n"); 00346 maxlen -= strlen(output); output += strlen(output); 00347 while(len > 2) { 00348 ie = iedata[0]; 00349 ielen = iedata[1]; 00350 if (ielen + 2> len) { 00351 snprintf(tmp, (int)sizeof(tmp), "Total Prov IE length of %d bytes exceeds remaining prov frame length of %d bytes\n", ielen + 2, len); 00352 ast_copy_string(output, tmp, maxlen); 00353 maxlen -= strlen(output); 00354 output += strlen(output); 00355 return; 00356 } 00357 found = 0; 00358 for (x=0;x<(int)sizeof(prov_ies) / (int)sizeof(prov_ies[0]); x++) { 00359 if (prov_ies[x].ie == ie) { 00360 if (prov_ies[x].dump) { 00361 prov_ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen); 00362 snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", prov_ies[x].name, interp); 00363 ast_copy_string(output, tmp, maxlen); 00364 maxlen -= strlen(output); output += strlen(output); 00365 } else { 00366 if (ielen) 00367 snprintf(interp, (int)sizeof(interp), "%d bytes", ielen); 00368 else 00369 strcpy(interp, "Present"); 00370 snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", prov_ies[x].name, interp); 00371 ast_copy_string(output, tmp, maxlen); 00372 maxlen -= strlen(output); output += strlen(output); 00373 } 00374 found++; 00375 } 00376 } 00377 if (!found) { 00378 snprintf(tmp, (int)sizeof(tmp), " Unknown Prov IE %03d : Present\n", ie); 00379 ast_copy_string(output, tmp, maxlen); 00380 maxlen -= strlen(output); output += strlen(output); 00381 } 00382 iedata += (2 + ielen); 00383 len -= (2 + ielen); 00384 } 00385 }
static void dump_samprate | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 194 of file iax2-parser.c.
References ast_copy_string(), IAX_RATE_11KHZ, IAX_RATE_16KHZ, IAX_RATE_22KHZ, IAX_RATE_44KHZ, IAX_RATE_48KHZ, and IAX_RATE_8KHZ.
00195 { 00196 char tmp[256]=""; 00197 int sr; 00198 if (len == (int)sizeof(unsigned short)) { 00199 sr = ntohs(*((unsigned short *)value)); 00200 if (sr & IAX_RATE_8KHZ) 00201 strcat(tmp, ",8khz"); 00202 if (sr & IAX_RATE_11KHZ) 00203 strcat(tmp, ",11.025khz"); 00204 if (sr & IAX_RATE_16KHZ) 00205 strcat(tmp, ",16khz"); 00206 if (sr & IAX_RATE_22KHZ) 00207 strcat(tmp, ",22.05khz"); 00208 if (sr & IAX_RATE_44KHZ) 00209 strcat(tmp, ",44.1khz"); 00210 if (sr & IAX_RATE_48KHZ) 00211 strcat(tmp, ",48khz"); 00212 if (strlen(tmp)) 00213 ast_copy_string(output, &tmp[1], maxlen); 00214 else 00215 ast_copy_string(output, "None Specified!\n", maxlen); 00216 } else 00217 ast_copy_string(output, "Invalid SHORT", maxlen); 00218 00219 }
static void dump_short | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 141 of file iax2-parser.c.
References ast_copy_string(), and get_unaligned_uint16().
00142 { 00143 if (len == (int)sizeof(unsigned short)) 00144 snprintf(output, maxlen, "%d", ntohs(get_unaligned_uint16(value))); 00145 else 00146 ast_copy_string(output, "Invalid SHORT", maxlen); 00147 }
static void dump_string | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 105 of file iax2-parser.c.
00106 { 00107 maxlen--; 00108 if (maxlen > len) 00109 maxlen = len; 00110 strncpy(output, value, maxlen); 00111 output[maxlen] = '\0'; 00112 }
static void dump_string_hex | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 95 of file iax2-parser.c.
00096 { 00097 int i = 0; 00098 00099 while (len-- && (i + 1) * 4 < maxlen) { 00100 sprintf(output + (4 * i), "\\x%2.2x", *((unsigned char *)value + i)); 00101 i++; 00102 } 00103 }
static void dump_versioned_codec | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 221 of file iax2-parser.c.
References ast_copy_string(), ast_getformatname(), get_unaligned_uint64(), ntohll(), and version.
00222 { 00223 char *version = (char *) value; 00224 if (version[0] == 0) { 00225 if (len == (int) (sizeof(format_t) + sizeof(char))) { 00226 format_t codec = ntohll(get_unaligned_uint64(value + 1)); 00227 ast_copy_string(output, ast_getformatname(codec), maxlen); 00228 } else { 00229 ast_copy_string(output, "Invalid length!", maxlen); 00230 } 00231 } else { 00232 ast_copy_string(output, "Unknown version!", maxlen); 00233 } 00234 }
static void frame_cache_cleanup | ( | void * | data | ) | [static] |
Definition at line 1271 of file iax2-parser.c.
References ast_free, AST_LIST_REMOVE_HEAD, iax_frame::list, and iax_frames::list.
01272 { 01273 struct iax_frames *framelist = data; 01274 struct iax_frame *current; 01275 01276 while ((current = AST_LIST_REMOVE_HEAD(&framelist->list, list))) 01277 ast_free(current); 01278 01279 ast_free(framelist); 01280 }
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, version, and iax_ies::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 *) | func | ) |
Definition at line 747 of file iax2-parser.c.
References errorf.
Referenced by load_module().
00748 { 00749 errorf = func; 00750 }
void iax_set_output | ( | void(*)(const char *) | func | ) |
Definition at line 742 of file iax2-parser.c.
References outputf.
Referenced by load_module().
00743 { 00744 outputf = func; 00745 }
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 }
static void internalerror | ( | const char * | str | ) | [static] |
Definition at line 76 of file iax2-parser.c.
00077 { 00078 fprintf(stderr, "WARNING: %s", str); 00079 }
static void internaloutput | ( | const char * | str | ) | [static] |
Definition at line 82 of file iax2-parser.c.
Referenced by dundi_ie_append_answer(), dundi_ie_append_cause(), dundi_ie_append_encdata(), dundi_ie_append_hint(), dundi_ie_append_raw(), dundi_parse_ies(), dundi_set_error(), iax_frame_free(), iax_ie_append_raw(), iax_parse_ies(), and iax_set_error().
struct ast_threadstorage frame_cache = { .once = PTHREAD_ONCE_INIT , .key_init = __init_frame_cache , .custom_init = NULL , } [static] |
Definition at line 57 of file iax2-parser.c.
Referenced by __frame_free(), ast_frame_header_new(), ast_frdup(), iax_frame_free(), and iax_frame_new().
int frames = 0 [static] |
Definition at line 49 of file iax2-parser.c.
Referenced by __ast_answer(), __ast_queue_frame(), __frame_free(), ast_frame_header_new(), ast_frdup(), ast_rtp_read(), fixed_jb_get(), frame_cache_cleanup(), process_dtmf_rfc2833(), and queue_put().
int iframes = 0 [static] |
Definition at line 50 of file iax2-parser.c.
Referenced by dump_ies(), dundi_ie2str(), and iax_ie2str().
int oframes = 0 [static] |
Definition at line 51 of file iax2-parser.c.
Definition at line 81 of file iax2-parser.c.
Referenced by dump_ies(), dundi_parse_ies(), dundi_set_output(), dundi_showframe(), iax_parse_ies(), iax_set_output(), and iax_showframe().