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