#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 64 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 80 of file iax2-parser.c.
References ast_copy_string(), and ast_inet_ntoa().
00081 { 00082 struct sockaddr_in sin; 00083 if (len == (int)sizeof(sin)) { 00084 memcpy(&sin, value, len); 00085 snprintf(output, maxlen, "IPV4 %s:%d", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 00086 } else { 00087 ast_copy_string(output, "Invalid Address", maxlen); 00088 } 00089 }
static void dump_byte | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 145 of file iax2-parser.c.
References ast_copy_string().
00146 { 00147 if (len == (int)sizeof(unsigned char)) 00148 snprintf(output, maxlen, "%d", *((unsigned char *)value)); 00149 else 00150 ast_copy_string(output, "Invalid BYTE", maxlen); 00151 }
static void dump_datetime | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 153 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.
00154 { 00155 struct ast_tm tm; 00156 unsigned long val = (unsigned long) ntohl(get_unaligned_uint32(value)); 00157 if (len == (int)sizeof(unsigned int)) { 00158 tm.tm_sec = (val & 0x1f) << 1; 00159 tm.tm_min = (val >> 5) & 0x3f; 00160 tm.tm_hour = (val >> 11) & 0x1f; 00161 tm.tm_mday = (val >> 16) & 0x1f; 00162 tm.tm_mon = ((val >> 21) & 0x0f) - 1; 00163 tm.tm_year = ((val >> 25) & 0x7f) + 100; 00164 ast_strftime(output, maxlen, "%Y-%m-%d %T", &tm); 00165 } else 00166 ast_copy_string(output, "Invalid DATETIME format!", maxlen); 00167 }
static void dump_ies | ( | unsigned char * | iedata, | |
int | len | |||
) | [static] |
Definition at line 383 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().
00384 { 00385 int ielen; 00386 int ie; 00387 int x; 00388 int found; 00389 char interp[1024]; 00390 char tmp[1024]; 00391 if (len < 2) 00392 return; 00393 while(len > 2) { 00394 ie = iedata[0]; 00395 ielen = iedata[1]; 00396 if (ielen + 2> len) { 00397 snprintf(tmp, (int)sizeof(tmp), "Total IE length of %d bytes exceeds remaining frame length of %d bytes\n", ielen + 2, len); 00398 outputf(tmp); 00399 return; 00400 } 00401 found = 0; 00402 for (x = 0; x < ARRAY_LEN(infoelts); x++) { 00403 if (infoelts[x].ie == ie) { 00404 if (infoelts[x].dump) { 00405 infoelts[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen); 00406 snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", infoelts[x].name, interp); 00407 outputf(tmp); 00408 } else { 00409 if (ielen) 00410 snprintf(interp, (int)sizeof(interp), "%d bytes", ielen); 00411 else 00412 strcpy(interp, "Present"); 00413 snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", infoelts[x].name, interp); 00414 outputf(tmp); 00415 } 00416 found++; 00417 } 00418 } 00419 if (!found) { 00420 snprintf(tmp, (int)sizeof(tmp), " Unknown IE %03d : Present\n", ie); 00421 outputf(tmp); 00422 } 00423 iedata += (2 + ielen); 00424 len -= (2 + ielen); 00425 } 00426 outputf("\n"); 00427 }
static void dump_int | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 129 of file iax2-parser.c.
References ast_copy_string(), and get_unaligned_uint32().
00130 { 00131 if (len == (int)sizeof(unsigned int)) 00132 snprintf(output, maxlen, "%lu", (unsigned long)ntohl(get_unaligned_uint32(value))); 00133 else 00134 ast_copy_string(output, "Invalid INT", maxlen); 00135 }
static void dump_ipaddr | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 169 of file iax2-parser.c.
References ast_copy_string(), and ast_inet_ntoa().
00170 { 00171 struct sockaddr_in sin; 00172 if (len == (int)sizeof(unsigned int)) { 00173 memcpy(&sin.sin_addr, value, len); 00174 snprintf(output, maxlen, "%s", ast_inet_ntoa(sin.sin_addr)); 00175 } else 00176 ast_copy_string(output, "Invalid IPADDR", maxlen); 00177 }
static void dump_prefs | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 110 of file iax2-parser.c.
References ast_codec_pref_convert(), and ast_codec_pref_string().
00111 { 00112 struct ast_codec_pref pref; 00113 int total_len = 0; 00114 00115 maxlen--; 00116 total_len = maxlen; 00117 00118 if (maxlen > len) 00119 maxlen = len; 00120 00121 strncpy(output, value, maxlen); 00122 output[maxlen] = '\0'; 00123 00124 ast_codec_pref_convert(&pref, output, total_len, 0); 00125 memset(output,0,total_len); 00126 ast_codec_pref_string(&pref, output, total_len); 00127 }
static void dump_prov | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 233 of file iax2-parser.c.
References dump_prov_ies().
00234 { 00235 dump_prov_ies(output, maxlen, value, len); 00236 }
static void dump_prov_flags | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 180 of file iax2-parser.c.
References ast_copy_string(), get_unaligned_uint32(), and iax_provflags2str().
00181 { 00182 char buf[256] = ""; 00183 if (len == (int)sizeof(unsigned int)) 00184 snprintf(output, maxlen, "%lu (%s)", (unsigned long)ntohl(get_unaligned_uint32(value)), 00185 iax_provflags2str(buf, sizeof(buf), ntohl(get_unaligned_uint32(value)))); 00186 else 00187 ast_copy_string(output, "Invalid INT", maxlen); 00188 }
static void dump_prov_ies | ( | char * | output, | |
int | maxlen, | |||
unsigned char * | iedata, | |||
int | len | |||
) | [static] |
Definition at line 331 of file iax2-parser.c.
References ast_copy_string(), iax2_ie::dump, iax2_ie::ie, name, and prov_ies.
Referenced by dump_prov().
00332 { 00333 int ielen; 00334 int ie; 00335 int x; 00336 int found; 00337 char interp[80]; 00338 char tmp[256]; 00339 if (len < 2) 00340 return; 00341 strcpy(output, "\n"); 00342 maxlen -= strlen(output); output += strlen(output); 00343 while(len > 2) { 00344 ie = iedata[0]; 00345 ielen = iedata[1]; 00346 if (ielen + 2> len) { 00347 snprintf(tmp, (int)sizeof(tmp), "Total Prov IE length of %d bytes exceeds remaining prov frame length of %d bytes\n", ielen + 2, len); 00348 ast_copy_string(output, tmp, maxlen); 00349 maxlen -= strlen(output); 00350 output += strlen(output); 00351 return; 00352 } 00353 found = 0; 00354 for (x=0;x<(int)sizeof(prov_ies) / (int)sizeof(prov_ies[0]); x++) { 00355 if (prov_ies[x].ie == ie) { 00356 if (prov_ies[x].dump) { 00357 prov_ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen); 00358 snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", prov_ies[x].name, interp); 00359 ast_copy_string(output, tmp, maxlen); 00360 maxlen -= strlen(output); output += strlen(output); 00361 } else { 00362 if (ielen) 00363 snprintf(interp, (int)sizeof(interp), "%d bytes", ielen); 00364 else 00365 strcpy(interp, "Present"); 00366 snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", prov_ies[x].name, interp); 00367 ast_copy_string(output, tmp, maxlen); 00368 maxlen -= strlen(output); output += strlen(output); 00369 } 00370 found++; 00371 } 00372 } 00373 if (!found) { 00374 snprintf(tmp, (int)sizeof(tmp), " Unknown Prov IE %03d : Present\n", ie); 00375 ast_copy_string(output, tmp, maxlen); 00376 maxlen -= strlen(output); output += strlen(output); 00377 } 00378 iedata += (2 + ielen); 00379 len -= (2 + ielen); 00380 } 00381 }
static void dump_samprate | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 190 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.
00191 { 00192 char tmp[256]=""; 00193 int sr; 00194 if (len == (int)sizeof(unsigned short)) { 00195 sr = ntohs(*((unsigned short *)value)); 00196 if (sr & IAX_RATE_8KHZ) 00197 strcat(tmp, ",8khz"); 00198 if (sr & IAX_RATE_11KHZ) 00199 strcat(tmp, ",11.025khz"); 00200 if (sr & IAX_RATE_16KHZ) 00201 strcat(tmp, ",16khz"); 00202 if (sr & IAX_RATE_22KHZ) 00203 strcat(tmp, ",22.05khz"); 00204 if (sr & IAX_RATE_44KHZ) 00205 strcat(tmp, ",44.1khz"); 00206 if (sr & IAX_RATE_48KHZ) 00207 strcat(tmp, ",48khz"); 00208 if (strlen(tmp)) 00209 ast_copy_string(output, &tmp[1], maxlen); 00210 else 00211 ast_copy_string(output, "None Specified!\n", maxlen); 00212 } else 00213 ast_copy_string(output, "Invalid SHORT", maxlen); 00214 00215 }
static void dump_short | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 137 of file iax2-parser.c.
References ast_copy_string(), and get_unaligned_uint16().
00138 { 00139 if (len == (int)sizeof(unsigned short)) 00140 snprintf(output, maxlen, "%d", ntohs(get_unaligned_uint16(value))); 00141 else 00142 ast_copy_string(output, "Invalid SHORT", maxlen); 00143 }
static void dump_string | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 101 of file iax2-parser.c.
00102 { 00103 maxlen--; 00104 if (maxlen > len) 00105 maxlen = len; 00106 strncpy(output, value, maxlen); 00107 output[maxlen] = '\0'; 00108 }
static void dump_string_hex | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 91 of file iax2-parser.c.
00092 { 00093 int i = 0; 00094 00095 while (len-- && (i + 1) * 4 < maxlen) { 00096 sprintf(output + (4 * i), "\\x%2.2x", *((unsigned char *)value + i)); 00097 i++; 00098 } 00099 }
static void dump_versioned_codec | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 217 of file iax2-parser.c.
References ast_copy_string(), ast_getformatname(), get_unaligned_uint64(), ntohll(), and version.
00218 { 00219 char *version = (char *) value; 00220 if (version[0] == 0) { 00221 if (len == (int) (sizeof(format_t) + sizeof(char))) { 00222 format_t codec = ntohll(get_unaligned_uint64(value + 1)); 00223 ast_copy_string(output, ast_getformatname(codec), maxlen); 00224 } else { 00225 ast_copy_string(output, "Invalid length!", maxlen); 00226 } 00227 } else { 00228 ast_copy_string(output, "Unknown version!", maxlen); 00229 } 00230 }
static void frame_cache_cleanup | ( | void * | data | ) | [static] |
Definition at line 1267 of file iax2-parser.c.
References ast_free, AST_LIST_REMOVE_HEAD, iax_frame::list, and iax_frames::list.
01268 { 01269 struct iax_frames *framelist = data; 01270 struct iax_frame *current; 01271 01272 while ((current = AST_LIST_REMOVE_HEAD(&framelist->list, list))) 01273 ast_free(current); 01274 01275 ast_free(framelist); 01276 }
void iax_frame_free | ( | struct iax_frame * | fr | ) |
Definition at line 1227 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().
01228 { 01229 #if !defined(LOW_MEMORY) 01230 struct iax_frames *iax_frames = NULL; 01231 #endif 01232 01233 /* Note: does not remove from scheduler! */ 01234 if (fr->direction == DIRECTION_INGRESS) 01235 ast_atomic_fetchadd_int(&iframes, -1); 01236 else if (fr->direction == DIRECTION_OUTGRESS) 01237 ast_atomic_fetchadd_int(&oframes, -1); 01238 else { 01239 errorf("Attempt to double free frame detected\n"); 01240 return; 01241 } 01242 ast_atomic_fetchadd_int(&frames, -1); 01243 01244 #if !defined(LOW_MEMORY) 01245 if (!fr->cacheable || !(iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) { 01246 ast_free(fr); 01247 return; 01248 } 01249 01250 if (iax_frames->size < FRAME_CACHE_MAX_SIZE) { 01251 fr->direction = 0; 01252 /* Pseudo-sort: keep smaller frames at the top of the list. This should 01253 * increase the chance that we pick the smallest applicable frame for use. */ 01254 if (AST_LIST_FIRST(&iax_frames->list) && AST_LIST_FIRST(&iax_frames->list)->afdatalen < fr->afdatalen) { 01255 AST_LIST_INSERT_TAIL(&iax_frames->list, fr, list); 01256 } else { 01257 AST_LIST_INSERT_HEAD(&iax_frames->list, fr, list); 01258 } 01259 iax_frames->size++; 01260 return; 01261 } 01262 #endif 01263 ast_free(fr); 01264 }
struct iax_frame* iax_frame_new | ( | int | direction, | |
int | datalen, | |||
unsigned int | cacheable | |||
) |
Definition at line 1169 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().
01170 { 01171 struct iax_frame *fr = NULL; 01172 01173 #if !defined(LOW_MEMORY) 01174 struct iax_frames *iax_frames = NULL; 01175 struct iax_frame *smallest = NULL; 01176 01177 /* Attempt to get a frame from this thread's cache */ 01178 if ((iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) { 01179 smallest = AST_LIST_FIRST(&iax_frames->list); 01180 AST_LIST_TRAVERSE_SAFE_BEGIN(&iax_frames->list, fr, list) { 01181 if (fr->afdatalen >= datalen) { 01182 size_t afdatalen = fr->afdatalen; 01183 AST_LIST_REMOVE_CURRENT(list); 01184 iax_frames->size--; 01185 memset(fr, 0, sizeof(*fr)); 01186 fr->afdatalen = afdatalen; 01187 break; 01188 } else if (smallest->afdatalen > fr->afdatalen) { 01189 smallest = fr; 01190 } 01191 } 01192 AST_LIST_TRAVERSE_SAFE_END; 01193 } 01194 if (!fr) { 01195 if (iax_frames->size >= FRAME_CACHE_MAX_SIZE && smallest) { 01196 /* Make useless cache into something more useful */ 01197 AST_LIST_REMOVE(&iax_frames->list, smallest, list); 01198 if (!(fr = ast_realloc(smallest, sizeof(*fr) + datalen))) { 01199 AST_LIST_INSERT_TAIL(&iax_frames->list, smallest, list); 01200 return NULL; 01201 } 01202 } else if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen))) 01203 return NULL; 01204 fr->afdatalen = datalen; 01205 } 01206 #else 01207 if (!(fr = ast_calloc(1, sizeof(*fr) + datalen))) 01208 return NULL; 01209 fr->afdatalen = datalen; 01210 #endif 01211 01212 01213 fr->direction = direction; 01214 fr->retrans = -1; 01215 fr->cacheable = cacheable; 01216 01217 if (fr->direction == DIRECTION_INGRESS) 01218 ast_atomic_fetchadd_int(&iframes, 1); 01219 else 01220 ast_atomic_fetchadd_int(&oframes, 1); 01221 01222 ast_atomic_fetchadd_int(&frames, 1); 01223 01224 return fr; 01225 }
void iax_frame_subclass2str | ( | enum iax_frame_subclass | subclass, | |
char * | str, | |||
size_t | len | |||
) |
Definition at line 429 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().
00430 { 00431 const char *cmd = "Unknown"; 00432 00433 /* if an error occurs here during compile, that means a new iax frame subclass 00434 * has been added to the iax_frame_subclass enum. Add the new subclass to the 00435 * switch case and make sure to update it with a new string representation. */ 00436 switch (subclass) { 00437 case IAX_COMMAND_NEW: 00438 cmd = "NEW "; 00439 break; 00440 case IAX_COMMAND_PING: 00441 cmd = "PING "; 00442 break; 00443 case IAX_COMMAND_PONG: 00444 cmd = "PONG "; 00445 break; 00446 case IAX_COMMAND_ACK: 00447 cmd = "ACK "; 00448 break; 00449 case IAX_COMMAND_HANGUP: 00450 cmd = "HANGUP "; 00451 break; 00452 case IAX_COMMAND_REJECT: 00453 cmd = "REJECT "; 00454 break; 00455 case IAX_COMMAND_ACCEPT: 00456 cmd = "ACCEPT "; 00457 break; 00458 case IAX_COMMAND_AUTHREQ: 00459 cmd = "AUTHREQ"; 00460 break; 00461 case IAX_COMMAND_AUTHREP: 00462 cmd = "AUTHREP"; 00463 break; 00464 case IAX_COMMAND_INVAL: 00465 cmd = "INVAL "; 00466 break; 00467 case IAX_COMMAND_LAGRQ: 00468 cmd = "LAGRQ "; 00469 break; 00470 case IAX_COMMAND_LAGRP: 00471 cmd = "LAGRP "; 00472 break; 00473 case IAX_COMMAND_REGREQ: 00474 cmd = "REGREQ "; 00475 break; 00476 case IAX_COMMAND_REGAUTH: 00477 cmd = "REGAUTH"; 00478 break; 00479 case IAX_COMMAND_REGACK: 00480 cmd = "REGACK "; 00481 break; 00482 case IAX_COMMAND_REGREJ: 00483 cmd = "REGREJ "; 00484 break; 00485 case IAX_COMMAND_REGREL: 00486 cmd = "REGREL "; 00487 break; 00488 case IAX_COMMAND_VNAK: 00489 cmd = "VNAK "; 00490 break; 00491 case IAX_COMMAND_DPREQ: 00492 cmd = "DPREQ "; 00493 break; 00494 case IAX_COMMAND_DPREP: 00495 cmd = "DPREP "; 00496 break; 00497 case IAX_COMMAND_DIAL: 00498 cmd = "DIAL "; 00499 break; 00500 case IAX_COMMAND_TXREQ: 00501 cmd = "TXREQ "; 00502 break; 00503 case IAX_COMMAND_TXCNT: 00504 cmd = "TXCNT "; 00505 break; 00506 case IAX_COMMAND_TXACC: 00507 cmd = "TXACC "; 00508 break; 00509 case IAX_COMMAND_TXREADY: 00510 cmd = "TXREADY"; 00511 break; 00512 case IAX_COMMAND_TXREL: 00513 cmd = "TXREL "; 00514 break; 00515 case IAX_COMMAND_TXREJ: 00516 cmd = "TXREJ "; 00517 break; 00518 case IAX_COMMAND_QUELCH: 00519 cmd = "QUELCH "; 00520 break; 00521 case IAX_COMMAND_UNQUELCH: 00522 cmd = "UNQULCH"; 00523 break; 00524 case IAX_COMMAND_POKE: 00525 cmd = "POKE "; 00526 break; 00527 case IAX_COMMAND_PAGE: 00528 cmd = "PAGE "; 00529 break; 00530 case IAX_COMMAND_MWI: 00531 cmd = "MWI "; 00532 break; 00533 case IAX_COMMAND_UNSUPPORT: 00534 cmd = "UNSPRTD"; 00535 break; 00536 case IAX_COMMAND_TRANSFER: 00537 cmd = "TRANSFR"; 00538 break; 00539 case IAX_COMMAND_PROVISION: 00540 cmd = "PROVISN"; 00541 break; 00542 case IAX_COMMAND_FWDOWNL: 00543 cmd = "FWDWNLD"; 00544 break; 00545 case IAX_COMMAND_FWDATA: 00546 cmd = "FWDATA "; 00547 break; 00548 case IAX_COMMAND_TXMEDIA: 00549 cmd = "TXMEDIA"; 00550 break; 00551 case IAX_COMMAND_RTKEY: 00552 cmd = "RTKEY "; 00553 break; 00554 case IAX_COMMAND_CALLTOKEN: 00555 cmd = "CTOKEN "; 00556 break; 00557 } 00558 ast_copy_string(str, cmd, len); 00559 }
Definition at line 1138 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().
01139 { 01140 fr->af.frametype = f->frametype; 01141 fr->af.subclass.codec = f->subclass.codec; 01142 fr->af.mallocd = 0; /* Our frame is static relative to the container */ 01143 fr->af.datalen = f->datalen; 01144 fr->af.samples = f->samples; 01145 fr->af.offset = AST_FRIENDLY_OFFSET; 01146 fr->af.src = f->src; 01147 fr->af.delivery.tv_sec = 0; 01148 fr->af.delivery.tv_usec = 0; 01149 fr->af.data.ptr = fr->afdata; 01150 fr->af.len = f->len; 01151 if (fr->af.datalen) { 01152 size_t copy_len = fr->af.datalen; 01153 if (copy_len > fr->afdatalen) { 01154 ast_log(LOG_ERROR, "Losing frame data because destination buffer size '%d' bytes not big enough for '%d' bytes in the frame\n", 01155 (int) fr->afdatalen, (int) fr->af.datalen); 01156 copy_len = fr->afdatalen; 01157 } 01158 #if __BYTE_ORDER == __LITTLE_ENDIAN 01159 /* We need to byte-swap slinear samples from network byte order */ 01160 if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass.codec == AST_FORMAT_SLINEAR)) { 01161 /* 2 bytes / sample for SLINEAR */ 01162 ast_swapcopy_samples(fr->af.data.ptr, f->data.ptr, copy_len / 2); 01163 } else 01164 #endif 01165 memcpy(fr->af.data.ptr, f->data.ptr, copy_len); 01166 } 01167 }
int iax_get_frames | ( | void | ) |
Definition at line 1279 of file iax2-parser.c.
Referenced by handle_cli_iax2_show_stats().
01279 { return frames; }
int iax_get_iframes | ( | void | ) |
Definition at line 1280 of file iax2-parser.c.
Referenced by handle_cli_iax2_show_stats().
01280 { return iframes; }
int iax_get_oframes | ( | void | ) |
Definition at line 1281 of file iax2-parser.c.
Referenced by handle_cli_iax2_show_stats().
01281 { return oframes; }
const char* iax_ie2str | ( | int | ie | ) |
Definition at line 320 of file iax2-parser.c.
References ARRAY_LEN, infoelts, and iax2_ie::name.
Referenced by iax_ie_append_raw(), and iax_parse_ies().
00321 { 00322 int x; 00323 for (x = 0; x < ARRAY_LEN(infoelts); x++) { 00324 if (infoelts[x].ie == ie) 00325 return infoelts[x].name; 00326 } 00327 return "Unknown IE"; 00328 }
int iax_ie_append | ( | struct iax_ie_data * | ied, | |
unsigned char | ie | |||
) |
Definition at line 733 of file iax2-parser.c.
References iax_ie_append_raw().
Referenced by iax2_call(), and iax_firmware_append().
00734 { 00735 return iax_ie_append_raw(ied, ie, NULL, 0); 00736 }
int iax_ie_append_addr | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
const struct sockaddr_in * | sin | |||
) |
Definition at line 694 of file iax2-parser.c.
References iax_ie_append_raw().
Referenced by iax2_start_transfer(), and update_registry().
00695 { 00696 return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in)); 00697 }
int iax_ie_append_byte | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
unsigned char | dat | |||
) |
Definition at line 728 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().
00729 { 00730 return iax_ie_append_raw(ied, ie, &dat, 1); 00731 }
int iax_ie_append_int | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
unsigned int | value | |||
) |
Definition at line 709 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().
00710 { 00711 unsigned int newval; 00712 newval = htonl(value); 00713 return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval)); 00714 }
int iax_ie_append_raw | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
const void * | data, | |||
int | datalen | |||
) |
Definition at line 679 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().
00680 { 00681 char tmp[256]; 00682 if (datalen > ((int)sizeof(ied->buf) - ied->pos)) { 00683 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); 00684 errorf(tmp); 00685 return -1; 00686 } 00687 ied->buf[ied->pos++] = ie; 00688 ied->buf[ied->pos++] = datalen; 00689 memcpy(ied->buf + ied->pos, data, datalen); 00690 ied->pos += datalen; 00691 return 0; 00692 }
int iax_ie_append_short | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
unsigned short | value | |||
) |
Definition at line 716 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().
00717 { 00718 unsigned short newval; 00719 newval = htons(value); 00720 return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval)); 00721 }
int iax_ie_append_str | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
const char * | str | |||
) |
Definition at line 723 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().
00724 { 00725 return iax_ie_append_raw(ied, ie, str, strlen(str)); 00726 }
int iax_ie_append_versioned_uint64 | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
unsigned char | version, | |||
uint64_t | value | |||
) |
Definition at line 699 of file iax2-parser.c.
References htonll(), iax_ie_append_raw(), and put_unaligned_uint64().
Referenced by iax2_call(), and socket_process().
00700 { 00701 struct _local { 00702 unsigned char version; 00703 uint64_t value; 00704 } __attribute__((packed)) newval = { version, }; 00705 put_unaligned_uint64(&newval.value, htonll(value)); 00706 return iax_ie_append_raw(ied, ie, &newval, (int) sizeof(newval)); 00707 }
int iax_parse_ies | ( | struct iax_ies * | ies, | |
unsigned char * | data, | |||
int | datalen | |||
) |
Definition at line 748 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().
00749 { 00750 /* Parse data into information elements */ 00751 int len; 00752 int ie; 00753 char tmp[256], *tmp2; 00754 struct ast_variable *var, *var2, *prev; 00755 unsigned int count; 00756 memset(ies, 0, (int)sizeof(struct iax_ies)); 00757 ies->msgcount = -1; 00758 ies->firmwarever = -1; 00759 ies->calling_ton = -1; 00760 ies->calling_tns = -1; 00761 ies->calling_pres = -1; 00762 ies->samprate = IAX_RATE_8KHZ; 00763 while(datalen >= 2) { 00764 ie = data[0]; 00765 len = data[1]; 00766 if (len > datalen - 2) { 00767 errorf("Information element length exceeds message size\n"); 00768 return -1; 00769 } 00770 switch(ie) { 00771 case IAX_IE_CALLED_NUMBER: 00772 ies->called_number = (char *)data + 2; 00773 break; 00774 case IAX_IE_CALLING_NUMBER: 00775 ies->calling_number = (char *)data + 2; 00776 break; 00777 case IAX_IE_CALLING_ANI: 00778 ies->calling_ani = (char *)data + 2; 00779 break; 00780 case IAX_IE_CALLING_NAME: 00781 ies->calling_name = (char *)data + 2; 00782 break; 00783 case IAX_IE_CALLED_CONTEXT: 00784 ies->called_context = (char *)data + 2; 00785 break; 00786 case IAX_IE_USERNAME: 00787 ies->username = (char *)data + 2; 00788 break; 00789 case IAX_IE_PASSWORD: 00790 ies->password = (char *)data + 2; 00791 break; 00792 case IAX_IE_CODEC_PREFS: 00793 ies->codec_prefs = (char *)data + 2; 00794 break; 00795 case IAX_IE_CAPABILITY: 00796 if (len != (int)sizeof(unsigned int)) { 00797 snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00798 errorf(tmp); 00799 } else if (ies->capability == 0) { /* Don't overwrite capability2, if specified */ 00800 ies->capability = ntohl(get_unaligned_uint32(data + 2)); 00801 } 00802 break; 00803 case IAX_IE_CAPABILITY2: 00804 { 00805 int version = data[2]; 00806 if (version == 0) { 00807 if (len != (int)sizeof(char) + sizeof(format_t)) { 00808 snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int) (sizeof(format_t) + sizeof(char)), len); 00809 errorf(tmp); 00810 } else { 00811 ies->capability = (format_t) ntohll(get_unaligned_uint64(data + 3)); 00812 } 00813 } /* else unknown version */ 00814 } 00815 break; 00816 case IAX_IE_FORMAT: 00817 if (len != (int)sizeof(unsigned int)) { 00818 snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00819 errorf(tmp); 00820 } else if (ies->format == 0) { /* Don't overwrite format2, if specified */ 00821 ies->format = ntohl(get_unaligned_uint32(data + 2)); 00822 } 00823 break; 00824 case IAX_IE_FORMAT2: 00825 { 00826 int version = data[2]; 00827 if (version == 0) { 00828 if (len != (int)sizeof(char) + sizeof(format_t)) { 00829 snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int) (sizeof(format_t) + sizeof(char)), len); 00830 errorf(tmp); 00831 } else { 00832 ies->format = (format_t) ntohll(get_unaligned_uint64(data + 3)); 00833 } 00834 } /* else unknown version */ 00835 } 00836 break; 00837 case IAX_IE_LANGUAGE: 00838 ies->language = (char *)data + 2; 00839 break; 00840 case IAX_IE_VERSION: 00841 if (len != (int)sizeof(unsigned short)) { 00842 snprintf(tmp, (int)sizeof(tmp), "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00843 errorf(tmp); 00844 } else 00845 ies->version = ntohs(get_unaligned_uint16(data + 2)); 00846 break; 00847 case IAX_IE_ADSICPE: 00848 if (len != (int)sizeof(unsigned short)) { 00849 snprintf(tmp, (int)sizeof(tmp), "Expecting adsicpe to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00850 errorf(tmp); 00851 } else 00852 ies->adsicpe = ntohs(get_unaligned_uint16(data + 2)); 00853 break; 00854 case IAX_IE_SAMPLINGRATE: 00855 if (len != (int)sizeof(unsigned short)) { 00856 snprintf(tmp, (int)sizeof(tmp), "Expecting samplingrate to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00857 errorf(tmp); 00858 } else 00859 ies->samprate = ntohs(get_unaligned_uint16(data + 2)); 00860 break; 00861 case IAX_IE_DNID: 00862 ies->dnid = (char *)data + 2; 00863 break; 00864 case IAX_IE_RDNIS: 00865 ies->rdnis = (char *)data + 2; 00866 break; 00867 case IAX_IE_AUTHMETHODS: 00868 if (len != (int)sizeof(unsigned short)) { 00869 snprintf(tmp, (int)sizeof(tmp), "Expecting authmethods to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00870 errorf(tmp); 00871 } else 00872 ies->authmethods = ntohs(get_unaligned_uint16(data + 2)); 00873 break; 00874 case IAX_IE_ENCRYPTION: 00875 if (len != (int)sizeof(unsigned short)) { 00876 snprintf(tmp, (int)sizeof(tmp), "Expecting encryption to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00877 errorf(tmp); 00878 } else 00879 ies->encmethods = ntohs(get_unaligned_uint16(data + 2)); 00880 break; 00881 case IAX_IE_CHALLENGE: 00882 ies->challenge = (char *)data + 2; 00883 break; 00884 case IAX_IE_MD5_RESULT: 00885 ies->md5_result = (char *)data + 2; 00886 break; 00887 case IAX_IE_RSA_RESULT: 00888 ies->rsa_result = (char *)data + 2; 00889 break; 00890 case IAX_IE_APPARENT_ADDR: 00891 ies->apparent_addr = ((struct sockaddr_in *)(data + 2)); 00892 break; 00893 case IAX_IE_REFRESH: 00894 if (len != (int)sizeof(unsigned short)) { 00895 snprintf(tmp, (int)sizeof(tmp), "Expecting refresh to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00896 errorf(tmp); 00897 } else 00898 ies->refresh = ntohs(get_unaligned_uint16(data + 2)); 00899 break; 00900 case IAX_IE_DPSTATUS: 00901 if (len != (int)sizeof(unsigned short)) { 00902 snprintf(tmp, (int)sizeof(tmp), "Expecting dpstatus to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00903 errorf(tmp); 00904 } else 00905 ies->dpstatus = ntohs(get_unaligned_uint16(data + 2)); 00906 break; 00907 case IAX_IE_CALLNO: 00908 if (len != (int)sizeof(unsigned short)) { 00909 snprintf(tmp, (int)sizeof(tmp), "Expecting callno to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00910 errorf(tmp); 00911 } else 00912 ies->callno = ntohs(get_unaligned_uint16(data + 2)); 00913 break; 00914 case IAX_IE_CAUSE: 00915 ies->cause = (char *)data + 2; 00916 break; 00917 case IAX_IE_CAUSECODE: 00918 if (len != 1) { 00919 snprintf(tmp, (int)sizeof(tmp), "Expecting causecode to be single byte but was %d\n", len); 00920 errorf(tmp); 00921 } else { 00922 ies->causecode = data[2]; 00923 } 00924 break; 00925 case IAX_IE_IAX_UNKNOWN: 00926 if (len == 1) 00927 ies->iax_unknown = data[2]; 00928 else { 00929 snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len); 00930 errorf(tmp); 00931 } 00932 break; 00933 case IAX_IE_MSGCOUNT: 00934 if (len != (int)sizeof(unsigned short)) { 00935 snprintf(tmp, (int)sizeof(tmp), "Expecting msgcount to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00936 errorf(tmp); 00937 } else 00938 ies->msgcount = ntohs(get_unaligned_uint16(data + 2)); 00939 break; 00940 case IAX_IE_AUTOANSWER: 00941 ies->autoanswer = 1; 00942 break; 00943 case IAX_IE_MUSICONHOLD: 00944 ies->musiconhold = 1; 00945 break; 00946 case IAX_IE_TRANSFERID: 00947 if (len != (int)sizeof(unsigned int)) { 00948 snprintf(tmp, (int)sizeof(tmp), "Expecting transferid to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00949 errorf(tmp); 00950 } else 00951 ies->transferid = ntohl(get_unaligned_uint32(data + 2)); 00952 break; 00953 case IAX_IE_DATETIME: 00954 if (len != (int)sizeof(unsigned int)) { 00955 snprintf(tmp, (int)sizeof(tmp), "Expecting date/time to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00956 errorf(tmp); 00957 } else 00958 ies->datetime = ntohl(get_unaligned_uint32(data + 2)); 00959 break; 00960 case IAX_IE_FIRMWAREVER: 00961 if (len != (int)sizeof(unsigned short)) { 00962 snprintf(tmp, (int)sizeof(tmp), "Expecting firmwarever to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00963 errorf(tmp); 00964 } else 00965 ies->firmwarever = ntohs(get_unaligned_uint16(data + 2)); 00966 break; 00967 case IAX_IE_DEVICETYPE: 00968 ies->devicetype = (char *)data + 2; 00969 break; 00970 case IAX_IE_SERVICEIDENT: 00971 ies->serviceident = (char *)data + 2; 00972 break; 00973 case IAX_IE_FWBLOCKDESC: 00974 if (len != (int)sizeof(unsigned int)) { 00975 snprintf(tmp, (int)sizeof(tmp), "Expected block desc to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00976 errorf(tmp); 00977 } else 00978 ies->fwdesc = ntohl(get_unaligned_uint32(data + 2)); 00979 break; 00980 case IAX_IE_FWBLOCKDATA: 00981 ies->fwdata = data + 2; 00982 ies->fwdatalen = len; 00983 break; 00984 case IAX_IE_ENCKEY: 00985 ies->enckey = data + 2; 00986 ies->enckeylen = len; 00987 break; 00988 case IAX_IE_PROVVER: 00989 if (len != (int)sizeof(unsigned int)) { 00990 snprintf(tmp, (int)sizeof(tmp), "Expected provisioning version to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00991 errorf(tmp); 00992 } else { 00993 ies->provverpres = 1; 00994 ies->provver = ntohl(get_unaligned_uint32(data + 2)); 00995 } 00996 break; 00997 case IAX_IE_CALLINGPRES: 00998 if (len == 1) 00999 ies->calling_pres = data[2]; 01000 else { 01001 snprintf(tmp, (int)sizeof(tmp), "Expected single byte callingpres, but was %d long\n", len); 01002 errorf(tmp); 01003 } 01004 break; 01005 case IAX_IE_CALLINGTON: 01006 if (len == 1) 01007 ies->calling_ton = data[2]; 01008 else { 01009 snprintf(tmp, (int)sizeof(tmp), "Expected single byte callington, but was %d long\n", len); 01010 errorf(tmp); 01011 } 01012 break; 01013 case IAX_IE_CALLINGTNS: 01014 if (len != (int)sizeof(unsigned short)) { 01015 snprintf(tmp, (int)sizeof(tmp), "Expecting callingtns to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 01016 errorf(tmp); 01017 } else 01018 ies->calling_tns = ntohs(get_unaligned_uint16(data + 2)); 01019 break; 01020 case IAX_IE_RR_JITTER: 01021 if (len != (int)sizeof(unsigned int)) { 01022 snprintf(tmp, (int)sizeof(tmp), "Expected jitter rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 01023 errorf(tmp); 01024 } else { 01025 ies->rr_jitter = ntohl(get_unaligned_uint32(data + 2)); 01026 } 01027 break; 01028 case IAX_IE_RR_LOSS: 01029 if (len != (int)sizeof(unsigned int)) { 01030 snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 01031 errorf(tmp); 01032 } else { 01033 ies->rr_loss = ntohl(get_unaligned_uint32(data + 2)); 01034 } 01035 break; 01036 case IAX_IE_RR_PKTS: 01037 if (len != (int)sizeof(unsigned int)) { 01038 snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 01039 errorf(tmp); 01040 } else { 01041 ies->rr_pkts = ntohl(get_unaligned_uint32(data + 2)); 01042 } 01043 break; 01044 case IAX_IE_RR_DELAY: 01045 if (len != (int)sizeof(unsigned short)) { 01046 snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 01047 errorf(tmp); 01048 } else { 01049 ies->rr_delay = ntohs(get_unaligned_uint16(data + 2)); 01050 } 01051 break; 01052 case IAX_IE_RR_DROPPED: 01053 if (len != (int)sizeof(unsigned int)) { 01054 snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 01055 errorf(tmp); 01056 } else { 01057 ies->rr_dropped = ntohl(get_unaligned_uint32(data + 2)); 01058 } 01059 break; 01060 case IAX_IE_RR_OOO: 01061 if (len != (int)sizeof(unsigned int)) { 01062 snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 01063 errorf(tmp); 01064 } else { 01065 ies->rr_ooo = ntohl(get_unaligned_uint32(data + 2)); 01066 } 01067 break; 01068 case IAX_IE_VARIABLE: 01069 ast_copy_string(tmp, (char *)data + 2, len + 1); 01070 tmp2 = strchr(tmp, '='); 01071 if (tmp2) 01072 *tmp2++ = '\0'; 01073 else 01074 tmp2 = ""; 01075 { 01076 struct ast_str *str = ast_str_create(16); 01077 /* Existing variable or new variable? */ 01078 for (var2 = ies->vars, prev = NULL; var2; prev = var2, var2 = var2->next) { 01079 if (strcmp(tmp, var2->name) == 0) { 01080 ast_str_set(&str, 0, "%s%s", var2->value, tmp2); 01081 var = ast_variable_new(tmp, ast_str_buffer(str), var2->file); 01082 var->next = var2->next; 01083 if (prev) { 01084 prev->next = var; 01085 } else { 01086 ies->vars = var; 01087 } 01088 snprintf(tmp, sizeof(tmp), "Assigned (%p)%s to (%p)%s\n", var->name, var->name, var->value, var->value); 01089 outputf(tmp); 01090 ast_free(var2); 01091 break; 01092 } 01093 } 01094 ast_free(str); 01095 } 01096 01097 if (!var2) { 01098 var = ast_variable_new(tmp, tmp2, ""); 01099 snprintf(tmp, sizeof(tmp), "Assigned (%p)%s to (%p)%s\n", var->name, var->name, var->value, var->value); 01100 outputf(tmp); 01101 var->next = ies->vars; 01102 ies->vars = var; 01103 } 01104 break; 01105 case IAX_IE_OSPTOKEN: 01106 if ((count = data[2]) < IAX_MAX_OSPBLOCK_NUM) { 01107 ies->osptokenblock[count] = (char *)data + 2 + 1; 01108 ies->ospblocklength[count] = len - 1; 01109 } else { 01110 snprintf(tmp, (int)sizeof(tmp), "Expected OSP token block index to be 0~%d but was %d\n", IAX_MAX_OSPBLOCK_NUM - 1, count); 01111 errorf(tmp); 01112 } 01113 break; 01114 case IAX_IE_CALLTOKEN: 01115 if (len) { 01116 ies->calltokendata = (unsigned char *) data + 2; 01117 } 01118 ies->calltoken = 1; 01119 break; 01120 default: 01121 snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len); 01122 outputf(tmp); 01123 } 01124 /* Overwrite information element with 0, to null terminate previous portion */ 01125 data[0] = 0; 01126 datalen -= (len + 2); 01127 data += (len + 2); 01128 } 01129 /* Null-terminate last field */ 01130 *data = '\0'; 01131 if (datalen) { 01132 errorf("Invalid information element contents, strange boundary\n"); 01133 return -1; 01134 } 01135 return 0; 01136 }
void iax_set_error | ( | void(*)(const char *) | func | ) |
Definition at line 743 of file iax2-parser.c.
References errorf.
Referenced by load_module().
00744 { 00745 errorf = func; 00746 }
void iax_set_output | ( | void(*)(const char *) | func | ) |
Definition at line 738 of file iax2-parser.c.
References outputf.
Referenced by load_module().
00739 { 00740 outputf = func; 00741 }
void iax_showframe | ( | struct iax_frame * | f, | |
struct ast_iax2_full_hdr * | fhi, | |||
int | rx, | |||
struct sockaddr_in * | sin, | |||
int | datalen | |||
) |
Definition at line 561 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().
00562 { 00563 const char *framelist[] = { 00564 "(0?)", 00565 "DTMF_E ", 00566 "VOICE ", 00567 "VIDEO ", 00568 "CONTROL", 00569 "NULL ", 00570 "IAX ", 00571 "TEXT ", 00572 "IMAGE ", 00573 "HTML ", 00574 "CNG ", 00575 "MODEM ", 00576 "DTMF_B ", 00577 }; 00578 const char *cmds[] = { 00579 "(0?)", 00580 "HANGUP ", 00581 "RING ", 00582 "RINGING", 00583 "ANSWER ", 00584 "BUSY ", 00585 "TKOFFHK", 00586 "OFFHOOK", 00587 "CONGSTN", 00588 "FLASH ", 00589 "WINK ", 00590 "OPTION ", 00591 "RDKEY ", 00592 "RDUNKEY", 00593 "PROGRES", 00594 "PROCDNG", 00595 "HOLD ", 00596 "UNHOLD ", 00597 "VIDUPDT", 00598 "T38 ", 00599 "SRCUPDT", 00600 "TXFER ", 00601 "CNLINE ", 00602 "REDIR ", 00603 }; 00604 struct ast_iax2_full_hdr *fh; 00605 char retries[20]; 00606 char class2[20]; 00607 char subclass2[20]; 00608 const char *class; 00609 const char *subclass; 00610 char *dir; 00611 char tmp[512]; 00612 00613 switch(rx) { 00614 case 0: 00615 dir = "Tx"; 00616 break; 00617 case 2: 00618 dir = "TE"; 00619 break; 00620 case 3: 00621 dir = "RD"; 00622 break; 00623 default: 00624 dir = "Rx"; 00625 break; 00626 } 00627 if (f) { 00628 fh = f->data; 00629 snprintf(retries, sizeof(retries), "%03d", f->retries); 00630 } else { 00631 fh = fhi; 00632 if (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) 00633 strcpy(retries, "Yes"); 00634 else 00635 strcpy(retries, " No"); 00636 } 00637 if (!(ntohs(fh->scallno) & IAX_FLAG_FULL)) { 00638 /* Don't mess with mini-frames */ 00639 return; 00640 } 00641 if (fh->type >= ARRAY_LEN(framelist)) { 00642 snprintf(class2, sizeof(class2), "(%d?)", fh->type); 00643 class = class2; 00644 } else { 00645 class = framelist[(int)fh->type]; 00646 } 00647 if (fh->type == AST_FRAME_DTMF_BEGIN || fh->type == AST_FRAME_DTMF_END) { 00648 sprintf(subclass2, "%c", fh->csub); 00649 subclass = subclass2; 00650 } else if (fh->type == AST_FRAME_IAX) { 00651 iax_frame_subclass2str((int)fh->csub, subclass2, sizeof(subclass2)); 00652 subclass = subclass2; 00653 } else if (fh->type == AST_FRAME_CONTROL) { 00654 if (fh->csub >= ARRAY_LEN(cmds)) { 00655 snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub); 00656 subclass = subclass2; 00657 } else { 00658 subclass = cmds[(int)fh->csub]; 00659 } 00660 } else { 00661 snprintf(subclass2, sizeof(subclass2), "%d", fh->csub); 00662 subclass = subclass2; 00663 } 00664 snprintf(tmp, sizeof(tmp), 00665 "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s Subclass: %s\n", 00666 dir, 00667 retries, fh->oseqno, fh->iseqno, class, subclass); 00668 outputf(tmp); 00669 snprintf(tmp, sizeof(tmp), 00670 " Timestamp: %05lums SCall: %5.5d DCall: %5.5d [%s:%d]\n", 00671 (unsigned long)ntohl(fh->ts), 00672 ntohs(fh->scallno) & ~IAX_FLAG_FULL, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, 00673 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 00674 outputf(tmp); 00675 if (fh->type == AST_FRAME_IAX) 00676 dump_ies(fh->iedata, datalen); 00677 }
static void internalerror | ( | const char * | str | ) | [static] |
Definition at line 72 of file iax2-parser.c.
00073 { 00074 fprintf(stderr, "WARNING: %s", str); 00075 }
static void internaloutput | ( | const char * | str | ) | [static] |
Definition at line 78 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 53 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 45 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 46 of file iax2-parser.c.
Referenced by dump_ies(), dundi_ie2str(), and iax_ie2str().
int oframes = 0 [static] |
Definition at line 47 of file iax2-parser.c.
Definition at line 77 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().