#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.h"
#include "asterisk/frame.h"
#include "asterisk/utils.h"
#include "asterisk/unaligned.h"
#include "iax2.h"
#include "iax2-parser.h"
#include "iax2-provision.h"
Include dependency graph for iax2-parser.c:
Go to the source code of this file.
Data Structures | |
struct | iax2_ie |
Functions | |
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) |
void | iax_frame_free (struct iax_frame *fr) |
iax_frame * | iax_frame_new (int direction, int datalen) |
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, 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, 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, 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.
static void dump_addr | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 62 of file iax2-parser.c.
References ast_inet_ntoa().
00063 { 00064 struct sockaddr_in sin; 00065 char iabuf[INET_ADDRSTRLEN]; 00066 if (len == (int)sizeof(sin)) { 00067 memcpy(&sin, value, len); 00068 snprintf(output, maxlen, "IPV4 %s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 00069 } else { 00070 snprintf(output, maxlen, "Invalid Address"); 00071 } 00072 }
static void dump_byte | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 118 of file iax2-parser.c.
00119 { 00120 if (len == (int)sizeof(unsigned char)) 00121 snprintf(output, maxlen, "%d", *((unsigned char *)value)); 00122 else 00123 ast_copy_string(output, "Invalid BYTE", maxlen); 00124 }
static void dump_datetime | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 126 of file iax2-parser.c.
References get_unaligned_uint32().
00127 { 00128 struct tm tm; 00129 unsigned long val = (unsigned long) ntohl(get_unaligned_uint32(value)); 00130 if (len == (int)sizeof(unsigned int)) { 00131 tm.tm_sec = (val & 0x1f) << 1; 00132 tm.tm_min = (val >> 5) & 0x3f; 00133 tm.tm_hour = (val >> 11) & 0x1f; 00134 tm.tm_mday = (val >> 16) & 0x1f; 00135 tm.tm_mon = ((val >> 21) & 0x0f) - 1; 00136 tm.tm_year = ((val >> 25) & 0x7f) + 100; 00137 strftime(output, maxlen, "%Y-%m-%d %T", &tm); 00138 } else 00139 ast_copy_string(output, "Invalid DATETIME format!", maxlen); 00140 }
static void dump_ies | ( | unsigned char * | iedata, | |
int | len | |||
) | [static] |
Definition at line 338 of file iax2-parser.c.
References iax2_ie::dump, iax2_ie::ie, ies, name, and outputf.
Referenced by dundi_showframe(), and iax_showframe().
00339 { 00340 int ielen; 00341 int ie; 00342 int x; 00343 int found; 00344 char interp[1024]; 00345 char tmp[1024]; 00346 if (len < 2) 00347 return; 00348 while(len > 2) { 00349 ie = iedata[0]; 00350 ielen = iedata[1]; 00351 if (ielen + 2> len) { 00352 snprintf(tmp, (int)sizeof(tmp), "Total IE length of %d bytes exceeds remaining frame length of %d bytes\n", ielen + 2, len); 00353 outputf(tmp); 00354 return; 00355 } 00356 found = 0; 00357 for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) { 00358 if (ies[x].ie == ie) { 00359 if (ies[x].dump) { 00360 ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen); 00361 snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", ies[x].name, interp); 00362 outputf(tmp); 00363 } else { 00364 if (ielen) 00365 snprintf(interp, (int)sizeof(interp), "%d bytes", ielen); 00366 else 00367 strcpy(interp, "Present"); 00368 snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", ies[x].name, interp); 00369 outputf(tmp); 00370 } 00371 found++; 00372 } 00373 } 00374 if (!found) { 00375 snprintf(tmp, (int)sizeof(tmp), " Unknown IE %03d : Present\n", ie); 00376 outputf(tmp); 00377 } 00378 iedata += (2 + ielen); 00379 len -= (2 + ielen); 00380 } 00381 outputf("\n"); 00382 }
static void dump_int | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 102 of file iax2-parser.c.
References get_unaligned_uint32().
00103 { 00104 if (len == (int)sizeof(unsigned int)) 00105 snprintf(output, maxlen, "%lu", (unsigned long)ntohl(get_unaligned_uint32(value))); 00106 else 00107 ast_copy_string(output, "Invalid INT", maxlen); 00108 }
static void dump_ipaddr | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 142 of file iax2-parser.c.
References ast_inet_ntoa().
00143 { 00144 struct sockaddr_in sin; 00145 char iabuf[INET_ADDRSTRLEN]; 00146 if (len == (int)sizeof(unsigned int)) { 00147 memcpy(&sin.sin_addr, value, len); 00148 ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr); 00149 snprintf(output, maxlen, "%s", iabuf); 00150 } else 00151 ast_copy_string(output, "Invalid IPADDR", maxlen); 00152 }
static void dump_prefs | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 83 of file iax2-parser.c.
References ast_codec_pref_convert(), and ast_codec_pref_string().
00084 { 00085 struct ast_codec_pref pref; 00086 int total_len = 0; 00087 00088 maxlen--; 00089 total_len = maxlen; 00090 00091 if (maxlen > len) 00092 maxlen = len; 00093 00094 strncpy(output, value, maxlen); 00095 output[maxlen] = '\0'; 00096 00097 ast_codec_pref_convert(&pref, output, total_len, 0); 00098 memset(output,0,total_len); 00099 ast_codec_pref_string(&pref, output, total_len); 00100 }
static void dump_prov | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 193 of file iax2-parser.c.
References dump_prov_ies().
00194 { 00195 dump_prov_ies(output, maxlen, value, len); 00196 }
static void dump_prov_flags | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 155 of file iax2-parser.c.
References get_unaligned_uint32(), and iax_provflags2str().
00156 { 00157 char buf[256] = ""; 00158 if (len == (int)sizeof(unsigned int)) 00159 snprintf(output, maxlen, "%lu (%s)", (unsigned long)ntohl(get_unaligned_uint32(value)), 00160 iax_provflags2str(buf, sizeof(buf), ntohl(get_unaligned_uint32(value)))); 00161 else 00162 ast_copy_string(output, "Invalid INT", maxlen); 00163 }
static void dump_prov_ies | ( | char * | output, | |
int | maxlen, | |||
unsigned char * | iedata, | |||
int | len | |||
) | [static] |
Definition at line 286 of file iax2-parser.c.
References iax2_ie::dump, iax2_ie::ie, name, and prov_ies.
Referenced by dump_prov().
00287 { 00288 int ielen; 00289 int ie; 00290 int x; 00291 int found; 00292 char interp[80]; 00293 char tmp[256]; 00294 if (len < 2) 00295 return; 00296 strcpy(output, "\n"); 00297 maxlen -= strlen(output); output += strlen(output); 00298 while(len > 2) { 00299 ie = iedata[0]; 00300 ielen = iedata[1]; 00301 if (ielen + 2> len) { 00302 snprintf(tmp, (int)sizeof(tmp), "Total Prov IE length of %d bytes exceeds remaining prov frame length of %d bytes\n", ielen + 2, len); 00303 ast_copy_string(output, tmp, maxlen); 00304 maxlen -= strlen(output); 00305 output += strlen(output); 00306 return; 00307 } 00308 found = 0; 00309 for (x=0;x<(int)sizeof(prov_ies) / (int)sizeof(prov_ies[0]); x++) { 00310 if (prov_ies[x].ie == ie) { 00311 if (prov_ies[x].dump) { 00312 prov_ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen); 00313 snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", prov_ies[x].name, interp); 00314 ast_copy_string(output, tmp, maxlen); 00315 maxlen -= strlen(output); output += strlen(output); 00316 } else { 00317 if (ielen) 00318 snprintf(interp, (int)sizeof(interp), "%d bytes", ielen); 00319 else 00320 strcpy(interp, "Present"); 00321 snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", prov_ies[x].name, interp); 00322 ast_copy_string(output, tmp, maxlen); 00323 maxlen -= strlen(output); output += strlen(output); 00324 } 00325 found++; 00326 } 00327 } 00328 if (!found) { 00329 snprintf(tmp, (int)sizeof(tmp), " Unknown Prov IE %03d : Present\n", ie); 00330 ast_copy_string(output, tmp, maxlen); 00331 maxlen -= strlen(output); output += strlen(output); 00332 } 00333 iedata += (2 + ielen); 00334 len -= (2 + ielen); 00335 } 00336 }
static void dump_samprate | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 165 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.
00166 { 00167 char tmp[256]=""; 00168 int sr; 00169 if (len == (int)sizeof(unsigned short)) { 00170 sr = ntohs(*((unsigned short *)value)); 00171 if (sr & IAX_RATE_8KHZ) 00172 strcat(tmp, ",8khz"); 00173 if (sr & IAX_RATE_11KHZ) 00174 strcat(tmp, ",11.025khz"); 00175 if (sr & IAX_RATE_16KHZ) 00176 strcat(tmp, ",16khz"); 00177 if (sr & IAX_RATE_22KHZ) 00178 strcat(tmp, ",22.05khz"); 00179 if (sr & IAX_RATE_44KHZ) 00180 strcat(tmp, ",44.1khz"); 00181 if (sr & IAX_RATE_48KHZ) 00182 strcat(tmp, ",48khz"); 00183 if (strlen(tmp)) 00184 ast_copy_string(output, &tmp[1], maxlen); 00185 else 00186 ast_copy_string(output, "None Specified!\n", maxlen); 00187 } else 00188 ast_copy_string(output, "Invalid SHORT", maxlen); 00189 00190 }
static void dump_short | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 110 of file iax2-parser.c.
References get_unaligned_uint16().
00111 { 00112 if (len == (int)sizeof(unsigned short)) 00113 snprintf(output, maxlen, "%d", ntohs(get_unaligned_uint16(value))); 00114 else 00115 ast_copy_string(output, "Invalid SHORT", maxlen); 00116 }
static void dump_string | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 74 of file iax2-parser.c.
00075 { 00076 maxlen--; 00077 if (maxlen > len) 00078 maxlen = len; 00079 strncpy(output, value, maxlen); 00080 output[maxlen] = '\0'; 00081 }
void iax_frame_free | ( | struct iax_frame * | fr | ) |
Definition at line 933 of file iax2-parser.c.
References iax_frame::direction, DIRECTION_INGRESS, DIRECTION_OUTGRESS, errorf, and free.
Referenced by iax2_frame_free().
00934 { 00935 /* Note: does not remove from scheduler! */ 00936 if (fr->direction == DIRECTION_INGRESS) 00937 iframes--; 00938 else if (fr->direction == DIRECTION_OUTGRESS) 00939 oframes--; 00940 else { 00941 errorf("Attempt to double free frame detected\n"); 00942 return; 00943 } 00944 fr->direction = 0; 00945 free(fr); 00946 frames--; 00947 }
struct iax_frame* iax_frame_new | ( | int | direction, | |
int | datalen | |||
) |
Definition at line 917 of file iax2-parser.c.
References iax_frame::direction, DIRECTION_INGRESS, malloc, and iax_frame::retrans.
Referenced by iax2_send(), and iaxfrdup2().
00918 { 00919 struct iax_frame *fr; 00920 fr = malloc((int)sizeof(struct iax_frame) + datalen); 00921 if (fr) { 00922 fr->direction = direction; 00923 fr->retrans = -1; 00924 frames++; 00925 if (fr->direction == DIRECTION_INGRESS) 00926 iframes++; 00927 else 00928 oframes++; 00929 } 00930 return fr; 00931 }
Definition at line 894 of file iax2-parser.c.
References iax_frame::af, iax_frame::afdata, AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_swapcopy_samples(), ast_frame::data, ast_frame::datalen, ast_frame::delivery, ast_frame::frametype, ast_frame::mallocd, ast_frame::offset, ast_frame::samples, ast_frame::src, and ast_frame::subclass.
Referenced by iax2_send(), iaxfrdup2(), and socket_read().
00895 { 00896 fr->af.frametype = f->frametype; 00897 fr->af.subclass = f->subclass; 00898 fr->af.mallocd = 0; /* Our frame is static relative to the container */ 00899 fr->af.datalen = f->datalen; 00900 fr->af.samples = f->samples; 00901 fr->af.offset = AST_FRIENDLY_OFFSET; 00902 fr->af.src = f->src; 00903 fr->af.delivery.tv_sec = 0; 00904 fr->af.delivery.tv_usec = 0; 00905 fr->af.data = fr->afdata; 00906 if (fr->af.datalen) { 00907 #if __BYTE_ORDER == __LITTLE_ENDIAN 00908 /* We need to byte-swap slinear samples from network byte order */ 00909 if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass == AST_FORMAT_SLINEAR)) { 00910 ast_swapcopy_samples(fr->af.data, f->data, fr->af.samples); 00911 } else 00912 #endif 00913 memcpy(fr->af.data, f->data, fr->af.datalen); 00914 } 00915 }
int iax_get_frames | ( | void | ) |
Definition at line 949 of file iax2-parser.c.
Referenced by iax2_show_stats().
00949 { return frames; }
int iax_get_iframes | ( | void | ) |
Definition at line 950 of file iax2-parser.c.
Referenced by iax2_show_stats().
00950 { return iframes; }
int iax_get_oframes | ( | void | ) |
Definition at line 951 of file iax2-parser.c.
Referenced by iax2_show_stats().
00951 { return oframes; }
const char* iax_ie2str | ( | int | ie | ) |
Definition at line 275 of file iax2-parser.c.
Referenced by iax_ie_append_raw(), and iax_parse_ies().
00276 { 00277 int x; 00278 for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) { 00279 if (ies[x].ie == ie) 00280 return ies[x].name; 00281 } 00282 return "Unknown IE"; 00283 }
int iax_ie_append | ( | struct iax_ie_data * | ied, | |
unsigned char | ie | |||
) |
Definition at line 571 of file iax2-parser.c.
References iax_ie_append_raw().
Referenced by iax2_call(), and iax_firmware_append().
00572 { 00573 return iax_ie_append_raw(ied, ie, NULL, 0); 00574 }
int iax_ie_append_addr | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
struct sockaddr_in * | sin | |||
) |
Definition at line 542 of file iax2-parser.c.
References iax_ie_append_raw().
Referenced by iax2_start_transfer(), and update_registry().
00543 { 00544 return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in)); 00545 }
int iax_ie_append_byte | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
unsigned char | dat | |||
) |
Definition at line 566 of file iax2-parser.c.
References iax_ie_append_raw().
Referenced by auth_reject(), authenticate_request(), auto_hangup(), iax2_call(), iax2_hangup(), iax_provision_build(), and socket_read().
00567 { 00568 return iax_ie_append_raw(ied, ie, &dat, 1); 00569 }
int iax_ie_append_int | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
unsigned int | value | |||
) |
Definition at line 547 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_read(), try_transfer(), and update_registry().
00548 { 00549 unsigned int newval; 00550 newval = htonl(value); 00551 return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval)); 00552 }
int iax_ie_append_raw | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
void * | data, | |||
int | datalen | |||
) |
Definition at line 527 of file iax2-parser.c.
References iax_ie_data::buf, errorf, iax_ie2str(), and iax_ie_data::pos.
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().
00528 { 00529 char tmp[256]; 00530 if (datalen > ((int)sizeof(ied->buf) - ied->pos)) { 00531 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); 00532 errorf(tmp); 00533 return -1; 00534 } 00535 ied->buf[ied->pos++] = ie; 00536 ied->buf[ied->pos++] = datalen; 00537 memcpy(ied->buf + ied->pos, data, datalen); 00538 ied->pos += datalen; 00539 return 0; 00540 }
int iax_ie_append_short | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
unsigned short | value | |||
) |
Definition at line 554 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_read(), and update_registry().
00555 { 00556 unsigned short newval; 00557 newval = htons(value); 00558 return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval)); 00559 }
int iax_ie_append_str | ( | struct iax_ie_data * | ied, | |
unsigned char | ie, | |||
char * | str | |||
) |
Definition at line 561 of file iax2-parser.c.
References iax_ie_append_raw().
Referenced by auth_reject(), authenticate(), authenticate_request(), auto_hangup(), cache_get_callno_locked(), dp_lookup(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_transfer(), iax_provision_build(), registry_authrequest(), registry_rerequest(), socket_read(), and update_registry().
00562 { 00563 return iax_ie_append_raw(ied, ie, str, strlen(str)); 00564 }
int iax_parse_ies | ( | struct iax_ies * | ies, | |
unsigned char * | data, | |||
int | datalen | |||
) |
Definition at line 586 of file iax2-parser.c.
References errorf, get_unaligned_uint16(), get_unaligned_uint32(), 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_CAPABILITY, 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_FWBLOCKDATA, IAX_IE_FWBLOCKDESC, IAX_IE_IAX_UNKNOWN, IAX_IE_LANGUAGE, IAX_IE_MD5_RESULT, IAX_IE_MSGCOUNT, IAX_IE_MUSICONHOLD, 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_VERSION, IAX_RATE_8KHZ, ies, and outputf.
Referenced by socket_read().
00587 { 00588 /* Parse data into information elements */ 00589 int len; 00590 int ie; 00591 char tmp[256]; 00592 memset(ies, 0, (int)sizeof(struct iax_ies)); 00593 ies->msgcount = -1; 00594 ies->firmwarever = -1; 00595 ies->calling_ton = -1; 00596 ies->calling_tns = -1; 00597 ies->calling_pres = -1; 00598 ies->samprate = IAX_RATE_8KHZ; 00599 while(datalen >= 2) { 00600 ie = data[0]; 00601 len = data[1]; 00602 if (len > datalen - 2) { 00603 errorf("Information element length exceeds message size\n"); 00604 return -1; 00605 } 00606 switch(ie) { 00607 case IAX_IE_CALLED_NUMBER: 00608 ies->called_number = (char *)data + 2; 00609 break; 00610 case IAX_IE_CALLING_NUMBER: 00611 ies->calling_number = (char *)data + 2; 00612 break; 00613 case IAX_IE_CALLING_ANI: 00614 ies->calling_ani = (char *)data + 2; 00615 break; 00616 case IAX_IE_CALLING_NAME: 00617 ies->calling_name = (char *)data + 2; 00618 break; 00619 case IAX_IE_CALLED_CONTEXT: 00620 ies->called_context = (char *)data + 2; 00621 break; 00622 case IAX_IE_USERNAME: 00623 ies->username = (char *)data + 2; 00624 break; 00625 case IAX_IE_PASSWORD: 00626 ies->password = (char *)data + 2; 00627 break; 00628 case IAX_IE_CODEC_PREFS: 00629 ies->codec_prefs = (char *)data + 2; 00630 break; 00631 case IAX_IE_CAPABILITY: 00632 if (len != (int)sizeof(unsigned int)) { 00633 snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00634 errorf(tmp); 00635 } else 00636 ies->capability = ntohl(get_unaligned_uint32(data + 2)); 00637 break; 00638 case IAX_IE_FORMAT: 00639 if (len != (int)sizeof(unsigned int)) { 00640 snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00641 errorf(tmp); 00642 } else 00643 ies->format = ntohl(get_unaligned_uint32(data + 2)); 00644 break; 00645 case IAX_IE_LANGUAGE: 00646 ies->language = (char *)data + 2; 00647 break; 00648 case IAX_IE_VERSION: 00649 if (len != (int)sizeof(unsigned short)) { 00650 snprintf(tmp, (int)sizeof(tmp), "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00651 errorf(tmp); 00652 } else 00653 ies->version = ntohs(get_unaligned_uint16(data + 2)); 00654 break; 00655 case IAX_IE_ADSICPE: 00656 if (len != (int)sizeof(unsigned short)) { 00657 snprintf(tmp, (int)sizeof(tmp), "Expecting adsicpe to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00658 errorf(tmp); 00659 } else 00660 ies->adsicpe = ntohs(get_unaligned_uint16(data + 2)); 00661 break; 00662 case IAX_IE_SAMPLINGRATE: 00663 if (len != (int)sizeof(unsigned short)) { 00664 snprintf(tmp, (int)sizeof(tmp), "Expecting samplingrate to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00665 errorf(tmp); 00666 } else 00667 ies->samprate = ntohs(get_unaligned_uint16(data + 2)); 00668 break; 00669 case IAX_IE_DNID: 00670 ies->dnid = (char *)data + 2; 00671 break; 00672 case IAX_IE_RDNIS: 00673 ies->rdnis = (char *)data + 2; 00674 break; 00675 case IAX_IE_AUTHMETHODS: 00676 if (len != (int)sizeof(unsigned short)) { 00677 snprintf(tmp, (int)sizeof(tmp), "Expecting authmethods to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00678 errorf(tmp); 00679 } else 00680 ies->authmethods = ntohs(get_unaligned_uint16(data + 2)); 00681 break; 00682 case IAX_IE_ENCRYPTION: 00683 if (len != (int)sizeof(unsigned short)) { 00684 snprintf(tmp, (int)sizeof(tmp), "Expecting encryption to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00685 errorf(tmp); 00686 } else 00687 ies->encmethods = ntohs(get_unaligned_uint16(data + 2)); 00688 break; 00689 case IAX_IE_CHALLENGE: 00690 ies->challenge = (char *)data + 2; 00691 break; 00692 case IAX_IE_MD5_RESULT: 00693 ies->md5_result = (char *)data + 2; 00694 break; 00695 case IAX_IE_RSA_RESULT: 00696 ies->rsa_result = (char *)data + 2; 00697 break; 00698 case IAX_IE_APPARENT_ADDR: 00699 ies->apparent_addr = ((struct sockaddr_in *)(data + 2)); 00700 break; 00701 case IAX_IE_REFRESH: 00702 if (len != (int)sizeof(unsigned short)) { 00703 snprintf(tmp, (int)sizeof(tmp), "Expecting refresh to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00704 errorf(tmp); 00705 } else 00706 ies->refresh = ntohs(get_unaligned_uint16(data + 2)); 00707 break; 00708 case IAX_IE_DPSTATUS: 00709 if (len != (int)sizeof(unsigned short)) { 00710 snprintf(tmp, (int)sizeof(tmp), "Expecting dpstatus to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00711 errorf(tmp); 00712 } else 00713 ies->dpstatus = ntohs(get_unaligned_uint16(data + 2)); 00714 break; 00715 case IAX_IE_CALLNO: 00716 if (len != (int)sizeof(unsigned short)) { 00717 snprintf(tmp, (int)sizeof(tmp), "Expecting callno to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00718 errorf(tmp); 00719 } else 00720 ies->callno = ntohs(get_unaligned_uint16(data + 2)); 00721 break; 00722 case IAX_IE_CAUSE: 00723 ies->cause = (char *)data + 2; 00724 break; 00725 case IAX_IE_CAUSECODE: 00726 if (len != 1) { 00727 snprintf(tmp, (int)sizeof(tmp), "Expecting causecode to be single byte but was %d\n", len); 00728 errorf(tmp); 00729 } else { 00730 ies->causecode = data[2]; 00731 } 00732 break; 00733 case IAX_IE_IAX_UNKNOWN: 00734 if (len == 1) 00735 ies->iax_unknown = data[2]; 00736 else { 00737 snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len); 00738 errorf(tmp); 00739 } 00740 break; 00741 case IAX_IE_MSGCOUNT: 00742 if (len != (int)sizeof(unsigned short)) { 00743 snprintf(tmp, (int)sizeof(tmp), "Expecting msgcount to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00744 errorf(tmp); 00745 } else 00746 ies->msgcount = ntohs(get_unaligned_uint16(data + 2)); 00747 break; 00748 case IAX_IE_AUTOANSWER: 00749 ies->autoanswer = 1; 00750 break; 00751 case IAX_IE_MUSICONHOLD: 00752 ies->musiconhold = 1; 00753 break; 00754 case IAX_IE_TRANSFERID: 00755 if (len != (int)sizeof(unsigned int)) { 00756 snprintf(tmp, (int)sizeof(tmp), "Expecting transferid to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00757 errorf(tmp); 00758 } else 00759 ies->transferid = ntohl(get_unaligned_uint32(data + 2)); 00760 break; 00761 case IAX_IE_DATETIME: 00762 if (len != (int)sizeof(unsigned int)) { 00763 snprintf(tmp, (int)sizeof(tmp), "Expecting date/time to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00764 errorf(tmp); 00765 } else 00766 ies->datetime = ntohl(get_unaligned_uint32(data + 2)); 00767 break; 00768 case IAX_IE_FIRMWAREVER: 00769 if (len != (int)sizeof(unsigned short)) { 00770 snprintf(tmp, (int)sizeof(tmp), "Expecting firmwarever to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00771 errorf(tmp); 00772 } else 00773 ies->firmwarever = ntohs(get_unaligned_uint16(data + 2)); 00774 break; 00775 case IAX_IE_DEVICETYPE: 00776 ies->devicetype = (char *)data + 2; 00777 break; 00778 case IAX_IE_SERVICEIDENT: 00779 ies->serviceident = (char *)data + 2; 00780 break; 00781 case IAX_IE_FWBLOCKDESC: 00782 if (len != (int)sizeof(unsigned int)) { 00783 snprintf(tmp, (int)sizeof(tmp), "Expected block desc to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00784 errorf(tmp); 00785 } else 00786 ies->fwdesc = ntohl(get_unaligned_uint32(data + 2)); 00787 break; 00788 case IAX_IE_FWBLOCKDATA: 00789 ies->fwdata = data + 2; 00790 ies->fwdatalen = len; 00791 break; 00792 case IAX_IE_ENCKEY: 00793 ies->enckey = data + 2; 00794 ies->enckeylen = len; 00795 break; 00796 case IAX_IE_PROVVER: 00797 if (len != (int)sizeof(unsigned int)) { 00798 snprintf(tmp, (int)sizeof(tmp), "Expected provisioning version to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00799 errorf(tmp); 00800 } else { 00801 ies->provverpres = 1; 00802 ies->provver = ntohl(get_unaligned_uint32(data + 2)); 00803 } 00804 break; 00805 case IAX_IE_CALLINGPRES: 00806 if (len == 1) 00807 ies->calling_pres = data[2]; 00808 else { 00809 snprintf(tmp, (int)sizeof(tmp), "Expected single byte callingpres, but was %d long\n", len); 00810 errorf(tmp); 00811 } 00812 break; 00813 case IAX_IE_CALLINGTON: 00814 if (len == 1) 00815 ies->calling_ton = data[2]; 00816 else { 00817 snprintf(tmp, (int)sizeof(tmp), "Expected single byte callington, but was %d long\n", len); 00818 errorf(tmp); 00819 } 00820 break; 00821 case IAX_IE_CALLINGTNS: 00822 if (len != (int)sizeof(unsigned short)) { 00823 snprintf(tmp, (int)sizeof(tmp), "Expecting callingtns to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00824 errorf(tmp); 00825 } else 00826 ies->calling_tns = ntohs(get_unaligned_uint16(data + 2)); 00827 break; 00828 case IAX_IE_RR_JITTER: 00829 if (len != (int)sizeof(unsigned int)) { 00830 snprintf(tmp, (int)sizeof(tmp), "Expected jitter rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00831 errorf(tmp); 00832 } else { 00833 ies->rr_jitter = ntohl(get_unaligned_uint32(data + 2)); 00834 } 00835 break; 00836 case IAX_IE_RR_LOSS: 00837 if (len != (int)sizeof(unsigned int)) { 00838 snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00839 errorf(tmp); 00840 } else { 00841 ies->rr_loss = ntohl(get_unaligned_uint32(data + 2)); 00842 } 00843 break; 00844 case IAX_IE_RR_PKTS: 00845 if (len != (int)sizeof(unsigned int)) { 00846 snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00847 errorf(tmp); 00848 } else { 00849 ies->rr_pkts = ntohl(get_unaligned_uint32(data + 2)); 00850 } 00851 break; 00852 case IAX_IE_RR_DELAY: 00853 if (len != (int)sizeof(unsigned short)) { 00854 snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00855 errorf(tmp); 00856 } else { 00857 ies->rr_delay = ntohs(get_unaligned_uint16(data + 2)); 00858 } 00859 break; 00860 case IAX_IE_RR_DROPPED: 00861 if (len != (int)sizeof(unsigned int)) { 00862 snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00863 errorf(tmp); 00864 } else { 00865 ies->rr_dropped = ntohl(get_unaligned_uint32(data + 2)); 00866 } 00867 break; 00868 case IAX_IE_RR_OOO: 00869 if (len != (int)sizeof(unsigned int)) { 00870 snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00871 errorf(tmp); 00872 } else { 00873 ies->rr_ooo = ntohl(get_unaligned_uint32(data + 2)); 00874 } 00875 break; 00876 default: 00877 snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len); 00878 outputf(tmp); 00879 } 00880 /* Overwrite information element with 0, to null terminate previous portion */ 00881 data[0] = 0; 00882 datalen -= (len + 2); 00883 data += (len + 2); 00884 } 00885 /* Null-terminate last field */ 00886 *data = '\0'; 00887 if (datalen) { 00888 errorf("Invalid information element contents, strange boundary\n"); 00889 return -1; 00890 } 00891 return 0; 00892 }
void iax_set_error | ( | void(*)(const char *) | func | ) |
Definition at line 581 of file iax2-parser.c.
References errorf.
Referenced by load_module().
00582 { 00583 errorf = func; 00584 }
void iax_set_output | ( | void(*)(const char *) | func | ) |
Definition at line 576 of file iax2-parser.c.
References outputf.
Referenced by load_module().
00577 { 00578 outputf = func; 00579 }
void iax_showframe | ( | struct iax_frame * | f, | |
struct ast_iax2_full_hdr * | fhi, | |||
int | rx, | |||
struct sockaddr_in * | sin, | |||
int | datalen | |||
) |
Definition at line 384 of file iax2-parser.c.
References AST_FRAME_CONTROL, AST_FRAME_DTMF, 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, iaxs, 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 iax2_send(), raw_hangup(), send_packet(), and socket_read().
00385 { 00386 const char *frames[] = { 00387 "(0?)", 00388 "DTMF ", 00389 "VOICE ", 00390 "VIDEO ", 00391 "CONTROL", 00392 "NULL ", 00393 "IAX ", 00394 "TEXT ", 00395 "IMAGE ", 00396 "HTML ", 00397 "CNG " }; 00398 const char *iaxs[] = { 00399 "(0?)", 00400 "NEW ", 00401 "PING ", 00402 "PONG ", 00403 "ACK ", 00404 "HANGUP ", 00405 "REJECT ", 00406 "ACCEPT ", 00407 "AUTHREQ", 00408 "AUTHREP", 00409 "INVAL ", 00410 "LAGRQ ", 00411 "LAGRP ", 00412 "REGREQ ", 00413 "REGAUTH", 00414 "REGACK ", 00415 "REGREJ ", 00416 "REGREL ", 00417 "VNAK ", 00418 "DPREQ ", 00419 "DPREP ", 00420 "DIAL ", 00421 "TXREQ ", 00422 "TXCNT ", 00423 "TXACC ", 00424 "TXREADY", 00425 "TXREL ", 00426 "TXREJ ", 00427 "QUELCH ", 00428 "UNQULCH", 00429 "POKE ", 00430 "PAGE ", 00431 "MWI ", 00432 "UNSPRTD", 00433 "TRANSFR", 00434 "PROVISN", 00435 "FWDWNLD", 00436 "FWDATA " 00437 }; 00438 const char *cmds[] = { 00439 "(0?)", 00440 "HANGUP ", 00441 "RING ", 00442 "RINGING", 00443 "ANSWER ", 00444 "BUSY ", 00445 "TKOFFHK", 00446 "OFFHOOK" }; 00447 struct ast_iax2_full_hdr *fh; 00448 char retries[20]; 00449 char class2[20]; 00450 char subclass2[20]; 00451 const char *class; 00452 const char *subclass; 00453 char *dir; 00454 char tmp[512]; 00455 char iabuf[INET_ADDRSTRLEN]; 00456 00457 switch(rx) { 00458 case 0: 00459 dir = "Tx"; 00460 break; 00461 case 2: 00462 dir = "TE"; 00463 break; 00464 case 3: 00465 dir = "RD"; 00466 break; 00467 default: 00468 dir = "Rx"; 00469 break; 00470 } 00471 if (f) { 00472 fh = f->data; 00473 snprintf(retries, sizeof(retries), "%03d", f->retries); 00474 } else { 00475 fh = fhi; 00476 if (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) 00477 strcpy(retries, "Yes"); 00478 else 00479 strcpy(retries, " No"); 00480 } 00481 if (!(ntohs(fh->scallno) & IAX_FLAG_FULL)) { 00482 /* Don't mess with mini-frames */ 00483 return; 00484 } 00485 if (fh->type >= (int)sizeof(frames)/(int)sizeof(frames[0])) { 00486 snprintf(class2, sizeof(class2), "(%d?)", fh->type); 00487 class = class2; 00488 } else { 00489 class = frames[(int)fh->type]; 00490 } 00491 if (fh->type == AST_FRAME_DTMF) { 00492 sprintf(subclass2, "%c", fh->csub); 00493 subclass = subclass2; 00494 } else if (fh->type == AST_FRAME_IAX) { 00495 if (fh->csub >= (int)sizeof(iaxs)/(int)sizeof(iaxs[0])) { 00496 snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub); 00497 subclass = subclass2; 00498 } else { 00499 subclass = iaxs[(int)fh->csub]; 00500 } 00501 } else if (fh->type == AST_FRAME_CONTROL) { 00502 if (fh->csub >= (int)sizeof(cmds)/(int)sizeof(cmds[0])) { 00503 snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub); 00504 subclass = subclass2; 00505 } else { 00506 subclass = cmds[(int)fh->csub]; 00507 } 00508 } else { 00509 snprintf(subclass2, sizeof(subclass2), "%d", fh->csub); 00510 subclass = subclass2; 00511 } 00512 snprintf(tmp, sizeof(tmp), 00513 "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s Subclass: %s\n", 00514 dir, 00515 retries, fh->oseqno, fh->iseqno, class, subclass); 00516 outputf(tmp); 00517 snprintf(tmp, sizeof(tmp), 00518 " Timestamp: %05lums SCall: %5.5d DCall: %5.5d [%s:%d]\n", 00519 (unsigned long)ntohl(fh->ts), 00520 ntohs(fh->scallno) & ~IAX_FLAG_FULL, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, 00521 ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port)); 00522 outputf(tmp); 00523 if (fh->type == AST_FRAME_IAX) 00524 dump_ies(fh->iedata, datalen); 00525 }
static void internalerror | ( | const char * | str | ) | [static] |
static void internaloutput | ( | const char * | str | ) | [static] |
void(*) errorf(const char *str) = internalerror [static] |
Definition at line 60 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] |
Referenced by authenticate_reply(), authenticate_verify(), check_access(), complete_dpreply(), complete_transfer(), dump_ies(), dundi_answer_entity(), dundi_answer_query(), dundi_ie2str(), dundi_parse_ies(), dundi_prop_precache(), handle_command_response(), iax2_ack_registry(), iax_ie2str(), iax_parse_ies(), register_verify(), registry_rerequest(), save_rr(), socket_read(), and try_transfer().
int iframes = 0 [static] |
Definition at line 46 of file iax2-parser.c.
int oframes = 0 [static] |
Definition at line 47 of file iax2-parser.c.
void(*) outputf(const char *str) = internaloutput [static] |
Definition at line 59 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().