#include "asterisk.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include "asterisk/frame.h"
#include "asterisk/utils.h"
#include "asterisk/unaligned.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 |
Functions | |
AST_LIST_HEAD_NOLOCK (iax_frames, 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, frame_cache_init, 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 | 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_wrap (struct iax_frame *fr, struct ast_frame *f) |
int | iax_get_frames (void) |
int | iax_get_iframes (void) |
int | iax_get_oframes (void) |
const char * | iax_ie2str (int ie) |
int | iax_ie_append (struct iax_ie_data *ied, unsigned char ie) |
int | iax_ie_append_addr (struct iax_ie_data *ied, unsigned char ie, const struct sockaddr_in *sin) |
int | iax_ie_append_byte (struct iax_ie_data *ied, unsigned char ie, unsigned char dat) |
int | iax_ie_append_int (struct iax_ie_data *ied, unsigned char ie, unsigned int value) |
int | iax_ie_append_raw (struct iax_ie_data *ied, unsigned char ie, const void *data, int datalen) |
int | iax_ie_append_short (struct iax_ie_data *ied, unsigned char ie, unsigned short value) |
int | iax_ie_append_str (struct iax_ie_data *ied, unsigned char ie, const char *str) |
int | iax_parse_ies (struct iax_ies *ies, unsigned char *data, int datalen) |
void | iax_set_error (void(*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 struct iax2_ie | ies [] |
static int | iframes = 0 |
static int | oframes = 0 |
static void(* | outputf )(const char *str) = internaloutput |
static struct iax2_ie | prov_ies [] |
Definition in file iax2-parser.c.
AST_LIST_HEAD_NOLOCK | ( | iax_frames | , | |
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 | , | |
frame_cache_init | , | |||
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 77 of file iax2-parser.c.
References ast_inet_ntoa().
00078 { 00079 struct sockaddr_in sin; 00080 if (len == (int)sizeof(sin)) { 00081 memcpy(&sin, value, len); 00082 snprintf(output, maxlen, "IPV4 %s:%d", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 00083 } else { 00084 snprintf(output, maxlen, "Invalid Address"); 00085 } 00086 }
static void dump_byte | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 132 of file iax2-parser.c.
00133 { 00134 if (len == (int)sizeof(unsigned char)) 00135 snprintf(output, maxlen, "%d", *((unsigned char *)value)); 00136 else 00137 ast_copy_string(output, "Invalid BYTE", maxlen); 00138 }
static void dump_datetime | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 140 of file iax2-parser.c.
References get_unaligned_uint32().
00141 { 00142 struct tm tm; 00143 unsigned long val = (unsigned long) ntohl(get_unaligned_uint32(value)); 00144 if (len == (int)sizeof(unsigned int)) { 00145 tm.tm_sec = (val & 0x1f) << 1; 00146 tm.tm_min = (val >> 5) & 0x3f; 00147 tm.tm_hour = (val >> 11) & 0x1f; 00148 tm.tm_mday = (val >> 16) & 0x1f; 00149 tm.tm_mon = ((val >> 21) & 0x0f) - 1; 00150 tm.tm_year = ((val >> 25) & 0x7f) + 100; 00151 strftime(output, maxlen, "%Y-%m-%d %T", &tm); 00152 } else 00153 ast_copy_string(output, "Invalid DATETIME format!", maxlen); 00154 }
static void dump_ies | ( | unsigned char * | iedata, | |
int | len | |||
) | [static] |
Definition at line 350 of file iax2-parser.c.
References iax2_ie::dump, iax2_ie::ie, ies, name, and outputf.
Referenced by dundi_showframe(), and iax_showframe().
00351 { 00352 int ielen; 00353 int ie; 00354 int x; 00355 int found; 00356 char interp[1024]; 00357 char tmp[1024]; 00358 if (len < 2) 00359 return; 00360 while(len > 2) { 00361 ie = iedata[0]; 00362 ielen = iedata[1]; 00363 if (ielen + 2> len) { 00364 snprintf(tmp, (int)sizeof(tmp), "Total IE length of %d bytes exceeds remaining frame length of %d bytes\n", ielen + 2, len); 00365 outputf(tmp); 00366 return; 00367 } 00368 found = 0; 00369 for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) { 00370 if (ies[x].ie == ie) { 00371 if (ies[x].dump) { 00372 ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen); 00373 snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", ies[x].name, interp); 00374 outputf(tmp); 00375 } else { 00376 if (ielen) 00377 snprintf(interp, (int)sizeof(interp), "%d bytes", ielen); 00378 else 00379 strcpy(interp, "Present"); 00380 snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", ies[x].name, interp); 00381 outputf(tmp); 00382 } 00383 found++; 00384 } 00385 } 00386 if (!found) { 00387 snprintf(tmp, (int)sizeof(tmp), " Unknown IE %03d : Present\n", ie); 00388 outputf(tmp); 00389 } 00390 iedata += (2 + ielen); 00391 len -= (2 + ielen); 00392 } 00393 outputf("\n"); 00394 }
static void dump_int | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 116 of file iax2-parser.c.
References get_unaligned_uint32().
00117 { 00118 if (len == (int)sizeof(unsigned int)) 00119 snprintf(output, maxlen, "%lu", (unsigned long)ntohl(get_unaligned_uint32(value))); 00120 else 00121 ast_copy_string(output, "Invalid INT", maxlen); 00122 }
static void dump_ipaddr | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 156 of file iax2-parser.c.
References ast_inet_ntoa().
00157 { 00158 struct sockaddr_in sin; 00159 if (len == (int)sizeof(unsigned int)) { 00160 memcpy(&sin.sin_addr, value, len); 00161 snprintf(output, maxlen, "%s", ast_inet_ntoa(sin.sin_addr)); 00162 } else 00163 ast_copy_string(output, "Invalid IPADDR", maxlen); 00164 }
static void dump_prefs | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 97 of file iax2-parser.c.
References ast_codec_pref_convert(), and ast_codec_pref_string().
00098 { 00099 struct ast_codec_pref pref; 00100 int total_len = 0; 00101 00102 maxlen--; 00103 total_len = maxlen; 00104 00105 if (maxlen > len) 00106 maxlen = len; 00107 00108 strncpy(output, value, maxlen); 00109 output[maxlen] = '\0'; 00110 00111 ast_codec_pref_convert(&pref, output, total_len, 0); 00112 memset(output,0,total_len); 00113 ast_codec_pref_string(&pref, output, total_len); 00114 }
static void dump_prov | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 205 of file iax2-parser.c.
References dump_prov_ies().
00206 { 00207 dump_prov_ies(output, maxlen, value, len); 00208 }
static void dump_prov_flags | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 167 of file iax2-parser.c.
References get_unaligned_uint32(), and iax_provflags2str().
00168 { 00169 char buf[256] = ""; 00170 if (len == (int)sizeof(unsigned int)) 00171 snprintf(output, maxlen, "%lu (%s)", (unsigned long)ntohl(get_unaligned_uint32(value)), 00172 iax_provflags2str(buf, sizeof(buf), ntohl(get_unaligned_uint32(value)))); 00173 else 00174 ast_copy_string(output, "Invalid INT", maxlen); 00175 }
static void dump_prov_ies | ( | char * | output, | |
int | maxlen, | |||
unsigned char * | iedata, | |||
int | len | |||
) | [static] |
Definition at line 298 of file iax2-parser.c.
References iax2_ie::dump, iax2_ie::ie, and name.
Referenced by dump_prov().
00299 { 00300 int ielen; 00301 int ie; 00302 int x; 00303 int found; 00304 char interp[80]; 00305 char tmp[256]; 00306 if (len < 2) 00307 return; 00308 strcpy(output, "\n"); 00309 maxlen -= strlen(output); output += strlen(output); 00310 while(len > 2) { 00311 ie = iedata[0]; 00312 ielen = iedata[1]; 00313 if (ielen + 2> len) { 00314 snprintf(tmp, (int)sizeof(tmp), "Total Prov IE length of %d bytes exceeds remaining prov frame length of %d bytes\n", ielen + 2, len); 00315 ast_copy_string(output, tmp, maxlen); 00316 maxlen -= strlen(output); 00317 output += strlen(output); 00318 return; 00319 } 00320 found = 0; 00321 for (x=0;x<(int)sizeof(prov_ies) / (int)sizeof(prov_ies[0]); x++) { 00322 if (prov_ies[x].ie == ie) { 00323 if (prov_ies[x].dump) { 00324 prov_ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen); 00325 snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", prov_ies[x].name, interp); 00326 ast_copy_string(output, tmp, maxlen); 00327 maxlen -= strlen(output); output += strlen(output); 00328 } else { 00329 if (ielen) 00330 snprintf(interp, (int)sizeof(interp), "%d bytes", ielen); 00331 else 00332 strcpy(interp, "Present"); 00333 snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", prov_ies[x].name, interp); 00334 ast_copy_string(output, tmp, maxlen); 00335 maxlen -= strlen(output); output += strlen(output); 00336 } 00337 found++; 00338 } 00339 } 00340 if (!found) { 00341 snprintf(tmp, (int)sizeof(tmp), " Unknown Prov IE %03d : Present\n", ie); 00342 ast_copy_string(output, tmp, maxlen); 00343 maxlen -= strlen(output); output += strlen(output); 00344 } 00345 iedata += (2 + ielen); 00346 len -= (2 + ielen); 00347 } 00348 }
static void dump_samprate | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 177 of file iax2-parser.c.
References IAX_RATE_11KHZ, IAX_RATE_16KHZ, IAX_RATE_22KHZ, IAX_RATE_44KHZ, IAX_RATE_48KHZ, and IAX_RATE_8KHZ.
00178 { 00179 char tmp[256]=""; 00180 int sr; 00181 if (len == (int)sizeof(unsigned short)) { 00182 sr = ntohs(*((unsigned short *)value)); 00183 if (sr & IAX_RATE_8KHZ) 00184 strcat(tmp, ",8khz"); 00185 if (sr & IAX_RATE_11KHZ) 00186 strcat(tmp, ",11.025khz"); 00187 if (sr & IAX_RATE_16KHZ) 00188 strcat(tmp, ",16khz"); 00189 if (sr & IAX_RATE_22KHZ) 00190 strcat(tmp, ",22.05khz"); 00191 if (sr & IAX_RATE_44KHZ) 00192 strcat(tmp, ",44.1khz"); 00193 if (sr & IAX_RATE_48KHZ) 00194 strcat(tmp, ",48khz"); 00195 if (strlen(tmp)) 00196 ast_copy_string(output, &tmp[1], maxlen); 00197 else 00198 ast_copy_string(output, "None Specified!\n", maxlen); 00199 } else 00200 ast_copy_string(output, "Invalid SHORT", maxlen); 00201 00202 }
static void dump_short | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 124 of file iax2-parser.c.
References get_unaligned_uint16().
00125 { 00126 if (len == (int)sizeof(unsigned short)) 00127 snprintf(output, maxlen, "%d", ntohs(get_unaligned_uint16(value))); 00128 else 00129 ast_copy_string(output, "Invalid SHORT", maxlen); 00130 }
static void dump_string | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 88 of file iax2-parser.c.
00089 { 00090 maxlen--; 00091 if (maxlen > len) 00092 maxlen = len; 00093 strncpy(output, value, maxlen); 00094 output[maxlen] = '\0'; 00095 }
static void frame_cache_cleanup | ( | void * | data | ) | [static] |
Definition at line 1028 of file iax2-parser.c.
References AST_LIST_REMOVE_HEAD, and free.
01029 { 01030 struct iax_frames *frames = data; 01031 struct iax_frame *cur; 01032 01033 while ((cur = AST_LIST_REMOVE_HEAD(frames, list))) 01034 free(cur); 01035 01036 free(frames); 01037 }
void iax_frame_free | ( | struct iax_frame * | fr | ) |
Definition at line 997 of file iax2-parser.c.
Referenced by iax2_frame_free(), and network_thread().
00998 { 00999 #if !defined(LOW_MEMORY) 01000 struct iax_frames *iax_frames; 01001 #endif 01002 01003 /* Note: does not remove from scheduler! */ 01004 if (fr->direction == DIRECTION_INGRESS) 01005 ast_atomic_fetchadd_int(&iframes, -1); 01006 else if (fr->direction == DIRECTION_OUTGRESS) 01007 ast_atomic_fetchadd_int(&oframes, -1); 01008 else { 01009 errorf("Attempt to double free frame detected\n"); 01010 return; 01011 } 01012 ast_atomic_fetchadd_int(&frames, -1); 01013 01014 #if !defined(LOW_MEMORY) 01015 if (!fr->cacheable || !(iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) { 01016 free(fr); 01017 return; 01018 } 01019 01020 fr->direction = 0; 01021 AST_LIST_INSERT_HEAD(iax_frames, fr, list); 01022 #else 01023 free(fr); 01024 #endif 01025 }
struct iax_frame* iax_frame_new | ( | int | direction, | |
int | datalen, | |||
unsigned int | cacheable | |||
) | [read] |
Definition at line 951 of file iax2-parser.c.
Referenced by iax2_send(), and iaxfrdup2().
00952 { 00953 struct iax_frame *fr = NULL; 00954 00955 #if !defined(LOW_MEMORY) 00956 struct iax_frames *iax_frames; 00957 00958 /* Attempt to get a frame from this thread's cache */ 00959 if ((iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) { 00960 AST_LIST_TRAVERSE_SAFE_BEGIN(iax_frames, fr, list) { 00961 if (fr->afdatalen >= datalen) { 00962 size_t afdatalen = fr->afdatalen; 00963 AST_LIST_REMOVE_CURRENT(iax_frames, list); 00964 memset(fr, 0, sizeof(*fr)); 00965 fr->afdatalen = afdatalen; 00966 break; 00967 } 00968 } 00969 AST_LIST_TRAVERSE_SAFE_END 00970 } 00971 if (!fr) { 00972 if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen))) 00973 return NULL; 00974 fr->afdatalen = datalen; 00975 } 00976 #else 00977 if (!(fr = ast_calloc(1, sizeof(*fr) + datalen))) 00978 return NULL; 00979 fr->afdatalen = datalen; 00980 #endif 00981 00982 00983 fr->direction = direction; 00984 fr->retrans = -1; 00985 fr->cacheable = cacheable; 00986 00987 if (fr->direction == DIRECTION_INGRESS) 00988 ast_atomic_fetchadd_int(&iframes, 1); 00989 else 00990 ast_atomic_fetchadd_int(&oframes, 1); 00991 00992 ast_atomic_fetchadd_int(&frames, 1); 00993 00994 return fr; 00995 }
Definition at line 920 of file iax2-parser.c.
Referenced by iax2_send(), iaxfrdup2(), and socket_process().
00921 { 00922 fr->af.frametype = f->frametype; 00923 fr->af.subclass = f->subclass; 00924 fr->af.mallocd = 0; /* Our frame is static relative to the container */ 00925 fr->af.datalen = f->datalen; 00926 fr->af.samples = f->samples; 00927 fr->af.offset = AST_FRIENDLY_OFFSET; 00928 fr->af.src = f->src; 00929 fr->af.delivery.tv_sec = 0; 00930 fr->af.delivery.tv_usec = 0; 00931 fr->af.data = fr->afdata; 00932 fr->af.len = f->len; 00933 if (fr->af.datalen) { 00934 size_t copy_len = fr->af.datalen; 00935 if (copy_len > fr->afdatalen) { 00936 ast_log(LOG_ERROR, "Losing frame data because destination buffer size '%d' bytes not big enough for '%d' bytes in the frame\n", 00937 (int) fr->afdatalen, (int) fr->af.datalen); 00938 copy_len = fr->afdatalen; 00939 } 00940 #if __BYTE_ORDER == __LITTLE_ENDIAN 00941 /* We need to byte-swap slinear samples from network byte order */ 00942 if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass == AST_FORMAT_SLINEAR)) { 00943 /* 2 bytes / sample for SLINEAR */ 00944 ast_swapcopy_samples(fr->af.data, f->data, copy_len / 2); 00945 } else 00946 #endif 00947 memcpy(fr->af.data, f->data, copy_len); 00948 } 00949 }
int iax_get_frames | ( | void | ) |
Definition at line 1040 of file iax2-parser.c.
Referenced by iax2_show_stats().
01040 { return frames; }
int iax_get_iframes | ( | void | ) |
Definition at line 1041 of file iax2-parser.c.
Referenced by iax2_show_stats().
01041 { return iframes; }
int iax_get_oframes | ( | void | ) |
Definition at line 1042 of file iax2-parser.c.
Referenced by iax2_show_stats().
01042 { return oframes; }
const char* iax_ie2str | ( | int | ie | ) |
Definition at line 287 of file iax2-parser.c.
Referenced by iax_ie_append_raw(), and iax_parse_ies().
00288 { 00289 int x; 00290 for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) { 00291 if (ies[x].ie == ie) 00292 return ies[x].name; 00293 } 00294 return "Unknown IE"; 00295 }
int iax_ie_append | ( | struct iax_ie_data * | ied, | |
unsigned char | ie | |||
) |
Definition at line 597 of file iax2-parser.c.
Referenced by iax2_call(), and iax_firmware_append().
00598 { 00599 return iax_ie_append_raw(ied, ie, NULL, 0); 00600 }
int iax_ie_append_addr | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
const struct sockaddr_in * | sin | |||
) |
Definition at line 568 of file iax2-parser.c.
Referenced by iax2_start_transfer(), and update_registry().
00569 { 00570 return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in)); 00571 }
int iax_ie_append_byte | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
unsigned char | dat | |||
) |
Definition at line 592 of file iax2-parser.c.
Referenced by __auth_reject(), __auto_hangup(), authenticate_request(), iax2_call(), iax2_hangup(), iax_provision_build(), and socket_process().
00593 { 00594 return iax_ie_append_raw(ied, ie, &dat, 1); 00595 }
int iax_ie_append_int | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
unsigned int | value | |||
) |
Definition at line 573 of file iax2-parser.c.
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().
00574 { 00575 unsigned int newval; 00576 newval = htonl(value); 00577 return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval)); 00578 }
int iax_ie_append_raw | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
const void * | data, | |||
int | datalen | |||
) |
Definition at line 553 of file iax2-parser.c.
Referenced by iax2_provision(), iax_firmware_append(), iax_ie_append(), iax_ie_append_addr(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), and iax_ie_append_str().
00554 { 00555 char tmp[256]; 00556 if (datalen > ((int)sizeof(ied->buf) - ied->pos)) { 00557 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); 00558 errorf(tmp); 00559 return -1; 00560 } 00561 ied->buf[ied->pos++] = ie; 00562 ied->buf[ied->pos++] = datalen; 00563 memcpy(ied->buf + ied->pos, data, datalen); 00564 ied->pos += datalen; 00565 return 0; 00566 }
int iax_ie_append_short | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
unsigned short | value | |||
) |
Definition at line 580 of file iax2-parser.c.
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().
00581 { 00582 unsigned short newval; 00583 newval = htons(value); 00584 return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval)); 00585 }
int iax_ie_append_str | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
const char * | str | |||
) |
Definition at line 587 of file iax2-parser.c.
Referenced by __auth_reject(), __auto_hangup(), authenticate(), authenticate_request(), cache_get_callno_locked(), dp_lookup(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_transfer(), iax_provision_build(), registry_authrequest(), registry_rerequest(), socket_process(), and update_registry().
00588 { 00589 return iax_ie_append_raw(ied, ie, str, strlen(str)); 00590 }
int iax_parse_ies | ( | struct iax_ies * | ies, | |
unsigned char * | data, | |||
int | datalen | |||
) |
Definition at line 612 of file iax2-parser.c.
Referenced by socket_process().
00613 { 00614 /* Parse data into information elements */ 00615 int len; 00616 int ie; 00617 char tmp[256]; 00618 memset(ies, 0, (int)sizeof(struct iax_ies)); 00619 ies->msgcount = -1; 00620 ies->firmwarever = -1; 00621 ies->calling_ton = -1; 00622 ies->calling_tns = -1; 00623 ies->calling_pres = -1; 00624 ies->samprate = IAX_RATE_8KHZ; 00625 while(datalen >= 2) { 00626 ie = data[0]; 00627 len = data[1]; 00628 if (len > datalen - 2) { 00629 errorf("Information element length exceeds message size\n"); 00630 return -1; 00631 } 00632 switch(ie) { 00633 case IAX_IE_CALLED_NUMBER: 00634 ies->called_number = (char *)data + 2; 00635 break; 00636 case IAX_IE_CALLING_NUMBER: 00637 ies->calling_number = (char *)data + 2; 00638 break; 00639 case IAX_IE_CALLING_ANI: 00640 ies->calling_ani = (char *)data + 2; 00641 break; 00642 case IAX_IE_CALLING_NAME: 00643 ies->calling_name = (char *)data + 2; 00644 break; 00645 case IAX_IE_CALLED_CONTEXT: 00646 ies->called_context = (char *)data + 2; 00647 break; 00648 case IAX_IE_USERNAME: 00649 ies->username = (char *)data + 2; 00650 break; 00651 case IAX_IE_PASSWORD: 00652 ies->password = (char *)data + 2; 00653 break; 00654 case IAX_IE_CODEC_PREFS: 00655 ies->codec_prefs = (char *)data + 2; 00656 break; 00657 case IAX_IE_CAPABILITY: 00658 if (len != (int)sizeof(unsigned int)) { 00659 snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00660 errorf(tmp); 00661 } else 00662 ies->capability = ntohl(get_unaligned_uint32(data + 2)); 00663 break; 00664 case IAX_IE_FORMAT: 00665 if (len != (int)sizeof(unsigned int)) { 00666 snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00667 errorf(tmp); 00668 } else 00669 ies->format = ntohl(get_unaligned_uint32(data + 2)); 00670 break; 00671 case IAX_IE_LANGUAGE: 00672 ies->language = (char *)data + 2; 00673 break; 00674 case IAX_IE_VERSION: 00675 if (len != (int)sizeof(unsigned short)) { 00676 snprintf(tmp, (int)sizeof(tmp), "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00677 errorf(tmp); 00678 } else 00679 ies->version = ntohs(get_unaligned_uint16(data + 2)); 00680 break; 00681 case IAX_IE_ADSICPE: 00682 if (len != (int)sizeof(unsigned short)) { 00683 snprintf(tmp, (int)sizeof(tmp), "Expecting adsicpe to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00684 errorf(tmp); 00685 } else 00686 ies->adsicpe = ntohs(get_unaligned_uint16(data + 2)); 00687 break; 00688 case IAX_IE_SAMPLINGRATE: 00689 if (len != (int)sizeof(unsigned short)) { 00690 snprintf(tmp, (int)sizeof(tmp), "Expecting samplingrate to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00691 errorf(tmp); 00692 } else 00693 ies->samprate = ntohs(get_unaligned_uint16(data + 2)); 00694 break; 00695 case IAX_IE_DNID: 00696 ies->dnid = (char *)data + 2; 00697 break; 00698 case IAX_IE_RDNIS: 00699 ies->rdnis = (char *)data + 2; 00700 break; 00701 case IAX_IE_AUTHMETHODS: 00702 if (len != (int)sizeof(unsigned short)) { 00703 snprintf(tmp, (int)sizeof(tmp), "Expecting authmethods to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00704 errorf(tmp); 00705 } else 00706 ies->authmethods = ntohs(get_unaligned_uint16(data + 2)); 00707 break; 00708 case IAX_IE_ENCRYPTION: 00709 if (len != (int)sizeof(unsigned short)) { 00710 snprintf(tmp, (int)sizeof(tmp), "Expecting encryption to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00711 errorf(tmp); 00712 } else 00713 ies->encmethods = ntohs(get_unaligned_uint16(data + 2)); 00714 break; 00715 case IAX_IE_CHALLENGE: 00716 ies->challenge = (char *)data + 2; 00717 break; 00718 case IAX_IE_MD5_RESULT: 00719 ies->md5_result = (char *)data + 2; 00720 break; 00721 case IAX_IE_RSA_RESULT: 00722 ies->rsa_result = (char *)data + 2; 00723 break; 00724 case IAX_IE_APPARENT_ADDR: 00725 ies->apparent_addr = ((struct sockaddr_in *)(data + 2)); 00726 break; 00727 case IAX_IE_REFRESH: 00728 if (len != (int)sizeof(unsigned short)) { 00729 snprintf(tmp, (int)sizeof(tmp), "Expecting refresh to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00730 errorf(tmp); 00731 } else 00732 ies->refresh = ntohs(get_unaligned_uint16(data + 2)); 00733 break; 00734 case IAX_IE_DPSTATUS: 00735 if (len != (int)sizeof(unsigned short)) { 00736 snprintf(tmp, (int)sizeof(tmp), "Expecting dpstatus to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00737 errorf(tmp); 00738 } else 00739 ies->dpstatus = ntohs(get_unaligned_uint16(data + 2)); 00740 break; 00741 case IAX_IE_CALLNO: 00742 if (len != (int)sizeof(unsigned short)) { 00743 snprintf(tmp, (int)sizeof(tmp), "Expecting callno to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00744 errorf(tmp); 00745 } else 00746 ies->callno = ntohs(get_unaligned_uint16(data + 2)); 00747 break; 00748 case IAX_IE_CAUSE: 00749 ies->cause = (char *)data + 2; 00750 break; 00751 case IAX_IE_CAUSECODE: 00752 if (len != 1) { 00753 snprintf(tmp, (int)sizeof(tmp), "Expecting causecode to be single byte but was %d\n", len); 00754 errorf(tmp); 00755 } else { 00756 ies->causecode = data[2]; 00757 } 00758 break; 00759 case IAX_IE_IAX_UNKNOWN: 00760 if (len == 1) 00761 ies->iax_unknown = data[2]; 00762 else { 00763 snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len); 00764 errorf(tmp); 00765 } 00766 break; 00767 case IAX_IE_MSGCOUNT: 00768 if (len != (int)sizeof(unsigned short)) { 00769 snprintf(tmp, (int)sizeof(tmp), "Expecting msgcount to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00770 errorf(tmp); 00771 } else 00772 ies->msgcount = ntohs(get_unaligned_uint16(data + 2)); 00773 break; 00774 case IAX_IE_AUTOANSWER: 00775 ies->autoanswer = 1; 00776 break; 00777 case IAX_IE_MUSICONHOLD: 00778 ies->musiconhold = 1; 00779 break; 00780 case IAX_IE_TRANSFERID: 00781 if (len != (int)sizeof(unsigned int)) { 00782 snprintf(tmp, (int)sizeof(tmp), "Expecting transferid to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00783 errorf(tmp); 00784 } else 00785 ies->transferid = ntohl(get_unaligned_uint32(data + 2)); 00786 break; 00787 case IAX_IE_DATETIME: 00788 if (len != (int)sizeof(unsigned int)) { 00789 snprintf(tmp, (int)sizeof(tmp), "Expecting date/time to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00790 errorf(tmp); 00791 } else 00792 ies->datetime = ntohl(get_unaligned_uint32(data + 2)); 00793 break; 00794 case IAX_IE_FIRMWAREVER: 00795 if (len != (int)sizeof(unsigned short)) { 00796 snprintf(tmp, (int)sizeof(tmp), "Expecting firmwarever to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00797 errorf(tmp); 00798 } else 00799 ies->firmwarever = ntohs(get_unaligned_uint16(data + 2)); 00800 break; 00801 case IAX_IE_DEVICETYPE: 00802 ies->devicetype = (char *)data + 2; 00803 break; 00804 case IAX_IE_SERVICEIDENT: 00805 ies->serviceident = (char *)data + 2; 00806 break; 00807 case IAX_IE_FWBLOCKDESC: 00808 if (len != (int)sizeof(unsigned int)) { 00809 snprintf(tmp, (int)sizeof(tmp), "Expected block desc to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00810 errorf(tmp); 00811 } else 00812 ies->fwdesc = ntohl(get_unaligned_uint32(data + 2)); 00813 break; 00814 case IAX_IE_FWBLOCKDATA: 00815 ies->fwdata = data + 2; 00816 ies->fwdatalen = len; 00817 break; 00818 case IAX_IE_ENCKEY: 00819 ies->enckey = data + 2; 00820 ies->enckeylen = len; 00821 break; 00822 case IAX_IE_PROVVER: 00823 if (len != (int)sizeof(unsigned int)) { 00824 snprintf(tmp, (int)sizeof(tmp), "Expected provisioning version to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00825 errorf(tmp); 00826 } else { 00827 ies->provverpres = 1; 00828 ies->provver = ntohl(get_unaligned_uint32(data + 2)); 00829 } 00830 break; 00831 case IAX_IE_CALLINGPRES: 00832 if (len == 1) 00833 ies->calling_pres = data[2]; 00834 else { 00835 snprintf(tmp, (int)sizeof(tmp), "Expected single byte callingpres, but was %d long\n", len); 00836 errorf(tmp); 00837 } 00838 break; 00839 case IAX_IE_CALLINGTON: 00840 if (len == 1) 00841 ies->calling_ton = data[2]; 00842 else { 00843 snprintf(tmp, (int)sizeof(tmp), "Expected single byte callington, but was %d long\n", len); 00844 errorf(tmp); 00845 } 00846 break; 00847 case IAX_IE_CALLINGTNS: 00848 if (len != (int)sizeof(unsigned short)) { 00849 snprintf(tmp, (int)sizeof(tmp), "Expecting callingtns to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00850 errorf(tmp); 00851 } else 00852 ies->calling_tns = ntohs(get_unaligned_uint16(data + 2)); 00853 break; 00854 case IAX_IE_RR_JITTER: 00855 if (len != (int)sizeof(unsigned int)) { 00856 snprintf(tmp, (int)sizeof(tmp), "Expected jitter rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00857 errorf(tmp); 00858 } else { 00859 ies->rr_jitter = ntohl(get_unaligned_uint32(data + 2)); 00860 } 00861 break; 00862 case IAX_IE_RR_LOSS: 00863 if (len != (int)sizeof(unsigned int)) { 00864 snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00865 errorf(tmp); 00866 } else { 00867 ies->rr_loss = ntohl(get_unaligned_uint32(data + 2)); 00868 } 00869 break; 00870 case IAX_IE_RR_PKTS: 00871 if (len != (int)sizeof(unsigned int)) { 00872 snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00873 errorf(tmp); 00874 } else { 00875 ies->rr_pkts = ntohl(get_unaligned_uint32(data + 2)); 00876 } 00877 break; 00878 case IAX_IE_RR_DELAY: 00879 if (len != (int)sizeof(unsigned short)) { 00880 snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00881 errorf(tmp); 00882 } else { 00883 ies->rr_delay = ntohs(get_unaligned_uint16(data + 2)); 00884 } 00885 break; 00886 case IAX_IE_RR_DROPPED: 00887 if (len != (int)sizeof(unsigned int)) { 00888 snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00889 errorf(tmp); 00890 } else { 00891 ies->rr_dropped = ntohl(get_unaligned_uint32(data + 2)); 00892 } 00893 break; 00894 case IAX_IE_RR_OOO: 00895 if (len != (int)sizeof(unsigned int)) { 00896 snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00897 errorf(tmp); 00898 } else { 00899 ies->rr_ooo = ntohl(get_unaligned_uint32(data + 2)); 00900 } 00901 break; 00902 default: 00903 snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len); 00904 outputf(tmp); 00905 } 00906 /* Overwrite information element with 0, to null terminate previous portion */ 00907 data[0] = 0; 00908 datalen -= (len + 2); 00909 data += (len + 2); 00910 } 00911 /* Null-terminate last field */ 00912 *data = '\0'; 00913 if (datalen) { 00914 errorf("Invalid information element contents, strange boundary\n"); 00915 return -1; 00916 } 00917 return 0; 00918 }
void iax_set_error | ( | void(*)(const char *) | func | ) |
void iax_set_output | ( | void(*)(const char *) | func | ) |
void iax_showframe | ( | struct iax_frame * | f, | |
struct ast_iax2_full_hdr * | fhi, | |||
int | rx, | |||
struct sockaddr_in * | sin, | |||
int | datalen | |||
) |
Definition at line 396 of file iax2-parser.c.
Referenced by iax2_send(), raw_hangup(), send_packet(), and socket_process().
00397 { 00398 const char *frames[] = { 00399 "(0?)", 00400 "DTMF_E ", 00401 "VOICE ", 00402 "VIDEO ", 00403 "CONTROL", 00404 "NULL ", 00405 "IAX ", 00406 "TEXT ", 00407 "IMAGE ", 00408 "HTML ", 00409 "CNG ", 00410 "MODEM ", 00411 "DTMF_B ", 00412 }; 00413 const char *iaxs[] = { 00414 "(0?)", 00415 "NEW ", 00416 "PING ", 00417 "PONG ", 00418 "ACK ", 00419 "HANGUP ", 00420 "REJECT ", 00421 "ACCEPT ", 00422 "AUTHREQ", 00423 "AUTHREP", 00424 "INVAL ", 00425 "LAGRQ ", 00426 "LAGRP ", 00427 "REGREQ ", 00428 "REGAUTH", 00429 "REGACK ", 00430 "REGREJ ", 00431 "REGREL ", 00432 "VNAK ", 00433 "DPREQ ", 00434 "DPREP ", 00435 "DIAL ", 00436 "TXREQ ", 00437 "TXCNT ", 00438 "TXACC ", 00439 "TXREADY", 00440 "TXREL ", 00441 "TXREJ ", 00442 "QUELCH ", 00443 "UNQULCH", 00444 "POKE ", 00445 "PAGE ", 00446 "MWI ", 00447 "UNSPRTD", 00448 "TRANSFR", 00449 "PROVISN", 00450 "FWDWNLD", 00451 "FWDATA ", 00452 "TXMEDIA" 00453 }; 00454 const char *cmds[] = { 00455 "(0?)", 00456 "HANGUP ", 00457 "RING ", 00458 "RINGING", 00459 "ANSWER ", 00460 "BUSY ", 00461 "TKOFFHK", 00462 "OFFHOOK", 00463 "CONGSTN", 00464 "FLASH ", 00465 "WINK ", 00466 "OPTION ", 00467 "RDKEY ", 00468 "RDUNKEY", 00469 "PROGRES", 00470 "PROCDNG", 00471 "HOLD ", 00472 "UNHOLD ", 00473 "VIDUPDT", }; 00474 struct ast_iax2_full_hdr *fh; 00475 char retries[20]; 00476 char class2[20]; 00477 char subclass2[20]; 00478 const char *class; 00479 const char *subclass; 00480 char *dir; 00481 char tmp[512]; 00482 00483 switch(rx) { 00484 case 0: 00485 dir = "Tx"; 00486 break; 00487 case 2: 00488 dir = "TE"; 00489 break; 00490 case 3: 00491 dir = "RD"; 00492 break; 00493 default: 00494 dir = "Rx"; 00495 break; 00496 } 00497 if (f) { 00498 fh = f->data; 00499 snprintf(retries, sizeof(retries), "%03d", f->retries); 00500 } else { 00501 fh = fhi; 00502 if (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) 00503 strcpy(retries, "Yes"); 00504 else 00505 strcpy(retries, " No"); 00506 } 00507 if (!(ntohs(fh->scallno) & IAX_FLAG_FULL)) { 00508 /* Don't mess with mini-frames */ 00509 return; 00510 } 00511 if (fh->type >= (int)sizeof(frames)/(int)sizeof(frames[0])) { 00512 snprintf(class2, sizeof(class2), "(%d?)", fh->type); 00513 class = class2; 00514 } else { 00515 class = frames[(int)fh->type]; 00516 } 00517 if (fh->type == AST_FRAME_DTMF_BEGIN || fh->type == AST_FRAME_DTMF_END) { 00518 sprintf(subclass2, "%c", fh->csub); 00519 subclass = subclass2; 00520 } else if (fh->type == AST_FRAME_IAX) { 00521 if (fh->csub >= (int)sizeof(iaxs)/(int)sizeof(iaxs[0])) { 00522 snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub); 00523 subclass = subclass2; 00524 } else { 00525 subclass = iaxs[(int)fh->csub]; 00526 } 00527 } else if (fh->type == AST_FRAME_CONTROL) { 00528 if (fh->csub >= (int)sizeof(cmds)/(int)sizeof(cmds[0])) { 00529 snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub); 00530 subclass = subclass2; 00531 } else { 00532 subclass = cmds[(int)fh->csub]; 00533 } 00534 } else { 00535 snprintf(subclass2, sizeof(subclass2), "%d", fh->csub); 00536 subclass = subclass2; 00537 } 00538 snprintf(tmp, sizeof(tmp), 00539 "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s Subclass: %s\n", 00540 dir, 00541 retries, fh->oseqno, fh->iseqno, class, subclass); 00542 outputf(tmp); 00543 snprintf(tmp, sizeof(tmp), 00544 " Timestamp: %05lums SCall: %5.5d DCall: %5.5d [%s:%d]\n", 00545 (unsigned long)ntohl(fh->ts), 00546 ntohs(fh->scallno) & ~IAX_FLAG_FULL, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, 00547 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 00548 outputf(tmp); 00549 if (fh->type == AST_FRAME_IAX) 00550 dump_ies(fh->iedata, datalen); 00551 }
static void internalerror | ( | const char * | str | ) | [static] |
static void internaloutput | ( | const char * | str | ) | [static] |
void(* errorf)(const char *str) = internalerror [static] |
Definition at line 75 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().
int frames = 0 [static] |
Definition at line 49 of file iax2-parser.c.
Referenced by ast_frame_free(), ast_frame_header_new(), ast_frdup(), fixed_jb_get(), frame_cache_cleanup(), and queue_put().
Referenced by dump_ies(), dundi_ie2str(), and iax_ie2str().
int iframes = 0 [static] |
Definition at line 50 of file iax2-parser.c.
int oframes = 0 [static] |
Definition at line 51 of file iax2-parser.c.
void(* outputf)(const char *str) = internaloutput [static] |
Definition at line 74 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().
Definition at line 267 of file iax2-parser.c.