#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"

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) |
| struct 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, and name.
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 950 of file iax2-parser.c.
References iax_frame::direction, DIRECTION_INGRESS, DIRECTION_OUTGRESS, errorf, and free.
Referenced by iax2_frame_free(), and network_thread().
00951 { 00952 /* Note: does not remove from scheduler! */ 00953 if (fr->direction == DIRECTION_INGRESS) 00954 iframes--; 00955 else if (fr->direction == DIRECTION_OUTGRESS) 00956 oframes--; 00957 else { 00958 errorf("Attempt to double free frame detected\n"); 00959 return; 00960 } 00961 fr->direction = 0; 00962 free(fr); 00963 frames--; 00964 }
| struct iax_frame* iax_frame_new | ( | int | direction, | |
| int | datalen | |||
| ) | [read] |
Definition at line 933 of file iax2-parser.c.
References iax_frame::afdatalen, iax_frame::direction, DIRECTION_INGRESS, malloc, and iax_frame::retrans.
Referenced by iax2_send(), and iaxfrdup2().
00934 { 00935 struct iax_frame *fr; 00936 fr = malloc((int)sizeof(struct iax_frame) + datalen); 00937 if (fr) { 00938 fr->afdatalen = datalen; 00939 fr->direction = direction; 00940 fr->retrans = -1; 00941 frames++; 00942 if (fr->direction == DIRECTION_INGRESS) 00943 iframes++; 00944 else 00945 oframes++; 00946 } 00947 return fr; 00948 }
Definition at line 903 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::data, ast_frame::datalen, ast_frame::delivery, ast_frame::frametype, LOG_ERROR, ast_frame::mallocd, ast_frame::offset, ast_frame::samples, ast_frame::src, and ast_frame::subclass.
Referenced by iax2_send(), iaxfrdup2(), and socket_read().
00904 { 00905 fr->af.frametype = f->frametype; 00906 fr->af.subclass = f->subclass; 00907 fr->af.mallocd = 0; /* Our frame is static relative to the container */ 00908 fr->af.datalen = f->datalen; 00909 fr->af.samples = f->samples; 00910 fr->af.offset = AST_FRIENDLY_OFFSET; 00911 fr->af.src = f->src; 00912 fr->af.delivery.tv_sec = 0; 00913 fr->af.delivery.tv_usec = 0; 00914 fr->af.data = fr->afdata; 00915 if (fr->af.datalen) { 00916 size_t copy_len = fr->af.datalen; 00917 if (copy_len > fr->afdatalen) { 00918 ast_log(LOG_ERROR, "Losing frame data because destination buffer size '%d' bytes not big enough for '%d' bytes in the frame\n", 00919 (int) fr->afdatalen, (int) fr->af.datalen); 00920 copy_len = fr->afdatalen; 00921 } 00922 #if __BYTE_ORDER == __LITTLE_ENDIAN 00923 /* We need to byte-swap slinear samples from network byte order */ 00924 if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass == AST_FORMAT_SLINEAR)) { 00925 /* 2 bytes / sample for SLINEAR */ 00926 ast_swapcopy_samples(fr->af.data, f->data, copy_len / 2); 00927 } else 00928 #endif 00929 memcpy(fr->af.data, f->data, copy_len); 00930 } 00931 }
| int iax_get_frames | ( | void | ) |
Definition at line 966 of file iax2-parser.c.
Referenced by iax2_show_stats().
00966 { return frames; }
| int iax_get_iframes | ( | void | ) |
Definition at line 967 of file iax2-parser.c.
Referenced by iax2_show_stats().
00967 { return iframes; }
| int iax_get_oframes | ( | void | ) |
Definition at line 968 of file iax2-parser.c.
Referenced by iax2_show_stats().
00968 { return oframes; }
| const char* iax_ie2str | ( | int | ie | ) |
Definition at line 275 of file iax2-parser.c.
References ies, and iax2_ie::name.
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 574 of file iax2-parser.c.
References iax_ie_append_raw().
Referenced by iax2_call(), and iax_firmware_append().
00575 { 00576 return iax_ie_append_raw(ied, ie, NULL, 0); 00577 }
| int iax_ie_append_addr | ( | struct iax_ie_data * | ied, | |
| unsigned char | ie, | |||
| struct sockaddr_in * | sin | |||
| ) |
Definition at line 545 of file iax2-parser.c.
References iax_ie_append_raw().
Referenced by iax2_start_transfer(), and update_registry().
00546 { 00547 return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in)); 00548 }
| int iax_ie_append_byte | ( | struct iax_ie_data * | ied, | |
| unsigned char | ie, | |||
| unsigned char | dat | |||
| ) |
Definition at line 569 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().
00570 { 00571 return iax_ie_append_raw(ied, ie, &dat, 1); 00572 }
| int iax_ie_append_int | ( | struct iax_ie_data * | ied, | |
| unsigned char | ie, | |||
| unsigned int | value | |||
| ) |
Definition at line 550 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().
00551 { 00552 unsigned int newval; 00553 newval = htonl(value); 00554 return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval)); 00555 }
| int iax_ie_append_raw | ( | struct iax_ie_data * | ied, | |
| unsigned char | ie, | |||
| void * | data, | |||
| int | datalen | |||
| ) |
Definition at line 530 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().
00531 { 00532 char tmp[256]; 00533 if (datalen > ((int)sizeof(ied->buf) - ied->pos)) { 00534 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); 00535 errorf(tmp); 00536 return -1; 00537 } 00538 ied->buf[ied->pos++] = ie; 00539 ied->buf[ied->pos++] = datalen; 00540 memcpy(ied->buf + ied->pos, data, datalen); 00541 ied->pos += datalen; 00542 return 0; 00543 }
| int iax_ie_append_short | ( | struct iax_ie_data * | ied, | |
| unsigned char | ie, | |||
| unsigned short | value | |||
| ) |
Definition at line 557 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().
00558 { 00559 unsigned short newval; 00560 newval = htons(value); 00561 return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval)); 00562 }
| int iax_ie_append_str | ( | struct iax_ie_data * | ied, | |
| unsigned char | ie, | |||
| char * | str | |||
| ) |
Definition at line 564 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(), handle_call_token(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_transfer(), iax_provision_build(), registry_authrequest(), registry_rerequest(), resend_with_token(), socket_read(), and update_registry().
00565 { 00566 return iax_ie_append_raw(ied, ie, str, strlen(str)); 00567 }
| int iax_parse_ies | ( | struct iax_ies * | ies, | |
| unsigned char * | data, | |||
| int | datalen | |||
| ) |
Definition at line 589 of file iax2-parser.c.
References iax_ies::adsicpe, iax_ies::apparent_addr, 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, iax_ies::firmwarever, iax_ies::format, iax_ies::fwdata, iax_ies::fwdatalen, iax_ies::fwdesc, 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_CALLTOKEN, 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, iax_ies::iax_unknown, iax_ies::language, iax_ies::md5_result, iax_ies::msgcount, iax_ies::musiconhold, 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, iax_ies::transferid, iax_ies::username, and iax_ies::version.
Referenced by socket_read().
00590 { 00591 /* Parse data into information elements */ 00592 int len; 00593 int ie; 00594 char tmp[256]; 00595 memset(ies, 0, (int)sizeof(struct iax_ies)); 00596 ies->msgcount = -1; 00597 ies->firmwarever = -1; 00598 ies->calling_ton = -1; 00599 ies->calling_tns = -1; 00600 ies->calling_pres = -1; 00601 ies->samprate = IAX_RATE_8KHZ; 00602 while(datalen >= 2) { 00603 ie = data[0]; 00604 len = data[1]; 00605 if (len > datalen - 2) { 00606 errorf("Information element length exceeds message size\n"); 00607 return -1; 00608 } 00609 switch(ie) { 00610 case IAX_IE_CALLED_NUMBER: 00611 ies->called_number = (char *)data + 2; 00612 break; 00613 case IAX_IE_CALLING_NUMBER: 00614 ies->calling_number = (char *)data + 2; 00615 break; 00616 case IAX_IE_CALLING_ANI: 00617 ies->calling_ani = (char *)data + 2; 00618 break; 00619 case IAX_IE_CALLING_NAME: 00620 ies->calling_name = (char *)data + 2; 00621 break; 00622 case IAX_IE_CALLED_CONTEXT: 00623 ies->called_context = (char *)data + 2; 00624 break; 00625 case IAX_IE_USERNAME: 00626 ies->username = (char *)data + 2; 00627 break; 00628 case IAX_IE_PASSWORD: 00629 ies->password = (char *)data + 2; 00630 break; 00631 case IAX_IE_CODEC_PREFS: 00632 ies->codec_prefs = (char *)data + 2; 00633 break; 00634 case IAX_IE_CAPABILITY: 00635 if (len != (int)sizeof(unsigned int)) { 00636 snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00637 errorf(tmp); 00638 } else 00639 ies->capability = ntohl(get_unaligned_uint32(data + 2)); 00640 break; 00641 case IAX_IE_FORMAT: 00642 if (len != (int)sizeof(unsigned int)) { 00643 snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00644 errorf(tmp); 00645 } else 00646 ies->format = ntohl(get_unaligned_uint32(data + 2)); 00647 break; 00648 case IAX_IE_LANGUAGE: 00649 ies->language = (char *)data + 2; 00650 break; 00651 case IAX_IE_VERSION: 00652 if (len != (int)sizeof(unsigned short)) { 00653 snprintf(tmp, (int)sizeof(tmp), "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00654 errorf(tmp); 00655 } else 00656 ies->version = ntohs(get_unaligned_uint16(data + 2)); 00657 break; 00658 case IAX_IE_ADSICPE: 00659 if (len != (int)sizeof(unsigned short)) { 00660 snprintf(tmp, (int)sizeof(tmp), "Expecting adsicpe to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00661 errorf(tmp); 00662 } else 00663 ies->adsicpe = ntohs(get_unaligned_uint16(data + 2)); 00664 break; 00665 case IAX_IE_SAMPLINGRATE: 00666 if (len != (int)sizeof(unsigned short)) { 00667 snprintf(tmp, (int)sizeof(tmp), "Expecting samplingrate to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00668 errorf(tmp); 00669 } else 00670 ies->samprate = ntohs(get_unaligned_uint16(data + 2)); 00671 break; 00672 case IAX_IE_DNID: 00673 ies->dnid = (char *)data + 2; 00674 break; 00675 case IAX_IE_RDNIS: 00676 ies->rdnis = (char *)data + 2; 00677 break; 00678 case IAX_IE_AUTHMETHODS: 00679 if (len != (int)sizeof(unsigned short)) { 00680 snprintf(tmp, (int)sizeof(tmp), "Expecting authmethods to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00681 errorf(tmp); 00682 } else 00683 ies->authmethods = ntohs(get_unaligned_uint16(data + 2)); 00684 break; 00685 case IAX_IE_ENCRYPTION: 00686 if (len != (int)sizeof(unsigned short)) { 00687 snprintf(tmp, (int)sizeof(tmp), "Expecting encryption to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00688 errorf(tmp); 00689 } else 00690 ies->encmethods = ntohs(get_unaligned_uint16(data + 2)); 00691 break; 00692 case IAX_IE_CHALLENGE: 00693 ies->challenge = (char *)data + 2; 00694 break; 00695 case IAX_IE_MD5_RESULT: 00696 ies->md5_result = (char *)data + 2; 00697 break; 00698 case IAX_IE_RSA_RESULT: 00699 ies->rsa_result = (char *)data + 2; 00700 break; 00701 case IAX_IE_APPARENT_ADDR: 00702 ies->apparent_addr = ((struct sockaddr_in *)(data + 2)); 00703 break; 00704 case IAX_IE_REFRESH: 00705 if (len != (int)sizeof(unsigned short)) { 00706 snprintf(tmp, (int)sizeof(tmp), "Expecting refresh to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00707 errorf(tmp); 00708 } else 00709 ies->refresh = ntohs(get_unaligned_uint16(data + 2)); 00710 break; 00711 case IAX_IE_DPSTATUS: 00712 if (len != (int)sizeof(unsigned short)) { 00713 snprintf(tmp, (int)sizeof(tmp), "Expecting dpstatus to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00714 errorf(tmp); 00715 } else 00716 ies->dpstatus = ntohs(get_unaligned_uint16(data + 2)); 00717 break; 00718 case IAX_IE_CALLNO: 00719 if (len != (int)sizeof(unsigned short)) { 00720 snprintf(tmp, (int)sizeof(tmp), "Expecting callno to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00721 errorf(tmp); 00722 } else 00723 ies->callno = ntohs(get_unaligned_uint16(data + 2)); 00724 break; 00725 case IAX_IE_CAUSE: 00726 ies->cause = (char *)data + 2; 00727 break; 00728 case IAX_IE_CAUSECODE: 00729 if (len != 1) { 00730 snprintf(tmp, (int)sizeof(tmp), "Expecting causecode to be single byte but was %d\n", len); 00731 errorf(tmp); 00732 } else { 00733 ies->causecode = data[2]; 00734 } 00735 break; 00736 case IAX_IE_IAX_UNKNOWN: 00737 if (len == 1) 00738 ies->iax_unknown = data[2]; 00739 else { 00740 snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len); 00741 errorf(tmp); 00742 } 00743 break; 00744 case IAX_IE_MSGCOUNT: 00745 if (len != (int)sizeof(unsigned short)) { 00746 snprintf(tmp, (int)sizeof(tmp), "Expecting msgcount to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00747 errorf(tmp); 00748 } else 00749 ies->msgcount = ntohs(get_unaligned_uint16(data + 2)); 00750 break; 00751 case IAX_IE_AUTOANSWER: 00752 ies->autoanswer = 1; 00753 break; 00754 case IAX_IE_MUSICONHOLD: 00755 ies->musiconhold = 1; 00756 break; 00757 case IAX_IE_TRANSFERID: 00758 if (len != (int)sizeof(unsigned int)) { 00759 snprintf(tmp, (int)sizeof(tmp), "Expecting transferid to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00760 errorf(tmp); 00761 } else 00762 ies->transferid = ntohl(get_unaligned_uint32(data + 2)); 00763 break; 00764 case IAX_IE_DATETIME: 00765 if (len != (int)sizeof(unsigned int)) { 00766 snprintf(tmp, (int)sizeof(tmp), "Expecting date/time to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00767 errorf(tmp); 00768 } else 00769 ies->datetime = ntohl(get_unaligned_uint32(data + 2)); 00770 break; 00771 case IAX_IE_FIRMWAREVER: 00772 if (len != (int)sizeof(unsigned short)) { 00773 snprintf(tmp, (int)sizeof(tmp), "Expecting firmwarever to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00774 errorf(tmp); 00775 } else 00776 ies->firmwarever = ntohs(get_unaligned_uint16(data + 2)); 00777 break; 00778 case IAX_IE_DEVICETYPE: 00779 ies->devicetype = (char *)data + 2; 00780 break; 00781 case IAX_IE_SERVICEIDENT: 00782 ies->serviceident = (char *)data + 2; 00783 break; 00784 case IAX_IE_FWBLOCKDESC: 00785 if (len != (int)sizeof(unsigned int)) { 00786 snprintf(tmp, (int)sizeof(tmp), "Expected block desc to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00787 errorf(tmp); 00788 } else 00789 ies->fwdesc = ntohl(get_unaligned_uint32(data + 2)); 00790 break; 00791 case IAX_IE_FWBLOCKDATA: 00792 ies->fwdata = data + 2; 00793 ies->fwdatalen = len; 00794 break; 00795 case IAX_IE_ENCKEY: 00796 ies->enckey = data + 2; 00797 ies->enckeylen = len; 00798 break; 00799 case IAX_IE_PROVVER: 00800 if (len != (int)sizeof(unsigned int)) { 00801 snprintf(tmp, (int)sizeof(tmp), "Expected provisioning version to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00802 errorf(tmp); 00803 } else { 00804 ies->provverpres = 1; 00805 ies->provver = ntohl(get_unaligned_uint32(data + 2)); 00806 } 00807 break; 00808 case IAX_IE_CALLINGPRES: 00809 if (len == 1) 00810 ies->calling_pres = data[2]; 00811 else { 00812 snprintf(tmp, (int)sizeof(tmp), "Expected single byte callingpres, but was %d long\n", len); 00813 errorf(tmp); 00814 } 00815 break; 00816 case IAX_IE_CALLINGTON: 00817 if (len == 1) 00818 ies->calling_ton = data[2]; 00819 else { 00820 snprintf(tmp, (int)sizeof(tmp), "Expected single byte callington, but was %d long\n", len); 00821 errorf(tmp); 00822 } 00823 break; 00824 case IAX_IE_CALLINGTNS: 00825 if (len != (int)sizeof(unsigned short)) { 00826 snprintf(tmp, (int)sizeof(tmp), "Expecting callingtns to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00827 errorf(tmp); 00828 } else 00829 ies->calling_tns = ntohs(get_unaligned_uint16(data + 2)); 00830 break; 00831 case IAX_IE_RR_JITTER: 00832 if (len != (int)sizeof(unsigned int)) { 00833 snprintf(tmp, (int)sizeof(tmp), "Expected jitter rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00834 errorf(tmp); 00835 } else { 00836 ies->rr_jitter = ntohl(get_unaligned_uint32(data + 2)); 00837 } 00838 break; 00839 case IAX_IE_RR_LOSS: 00840 if (len != (int)sizeof(unsigned int)) { 00841 snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00842 errorf(tmp); 00843 } else { 00844 ies->rr_loss = ntohl(get_unaligned_uint32(data + 2)); 00845 } 00846 break; 00847 case IAX_IE_RR_PKTS: 00848 if (len != (int)sizeof(unsigned int)) { 00849 snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00850 errorf(tmp); 00851 } else { 00852 ies->rr_pkts = ntohl(get_unaligned_uint32(data + 2)); 00853 } 00854 break; 00855 case IAX_IE_RR_DELAY: 00856 if (len != (int)sizeof(unsigned short)) { 00857 snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00858 errorf(tmp); 00859 } else { 00860 ies->rr_delay = ntohs(get_unaligned_uint16(data + 2)); 00861 } 00862 break; 00863 case IAX_IE_RR_DROPPED: 00864 if (len != (int)sizeof(unsigned int)) { 00865 snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00866 errorf(tmp); 00867 } else { 00868 ies->rr_dropped = ntohl(get_unaligned_uint32(data + 2)); 00869 } 00870 break; 00871 case IAX_IE_RR_OOO: 00872 if (len != (int)sizeof(unsigned int)) { 00873 snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00874 errorf(tmp); 00875 } else { 00876 ies->rr_ooo = ntohl(get_unaligned_uint32(data + 2)); 00877 } 00878 break; 00879 case IAX_IE_CALLTOKEN: 00880 if (len) { 00881 ies->calltokendata = (unsigned char *) data + 2; 00882 } 00883 ies->calltoken = 1; 00884 break; 00885 default: 00886 snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len); 00887 outputf(tmp); 00888 } 00889 /* Overwrite information element with 0, to null terminate previous portion */ 00890 data[0] = 0; 00891 datalen -= (len + 2); 00892 data += (len + 2); 00893 } 00894 /* Null-terminate last field */ 00895 *data = '\0'; 00896 if (datalen) { 00897 errorf("Invalid information element contents, strange boundary\n"); 00898 return -1; 00899 } 00900 return 0; 00901 }
| void iax_set_error | ( | void(*)(const char *) | func | ) |
Definition at line 584 of file iax2-parser.c.
References errorf.
Referenced by load_module().
00585 { 00586 errorf = func; 00587 }
| void iax_set_output | ( | void(*)(const char *) | func | ) |
Definition at line 579 of file iax2-parser.c.
References outputf.
Referenced by load_module().
00580 { 00581 outputf = func; 00582 }
| 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 "TXMEDIA", 00438 "RTKEY ", 00439 "CTOKEN ", 00440 }; 00441 const char *cmds[] = { 00442 "(0?)", 00443 "HANGUP ", 00444 "RING ", 00445 "RINGING", 00446 "ANSWER ", 00447 "BUSY ", 00448 "TKOFFHK", 00449 "OFFHOOK" }; 00450 struct ast_iax2_full_hdr *fh; 00451 char retries[20]; 00452 char class2[20]; 00453 char subclass2[20]; 00454 const char *class; 00455 const char *subclass; 00456 char *dir; 00457 char tmp[512]; 00458 char iabuf[INET_ADDRSTRLEN]; 00459 00460 switch(rx) { 00461 case 0: 00462 dir = "Tx"; 00463 break; 00464 case 2: 00465 dir = "TE"; 00466 break; 00467 case 3: 00468 dir = "RD"; 00469 break; 00470 default: 00471 dir = "Rx"; 00472 break; 00473 } 00474 if (f) { 00475 fh = f->data; 00476 snprintf(retries, sizeof(retries), "%03d", f->retries); 00477 } else { 00478 fh = fhi; 00479 if (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) 00480 strcpy(retries, "Yes"); 00481 else 00482 strcpy(retries, " No"); 00483 } 00484 if (!(ntohs(fh->scallno) & IAX_FLAG_FULL)) { 00485 /* Don't mess with mini-frames */ 00486 return; 00487 } 00488 if (fh->type >= (int)sizeof(frames)/(int)sizeof(frames[0])) { 00489 snprintf(class2, sizeof(class2), "(%d?)", fh->type); 00490 class = class2; 00491 } else { 00492 class = frames[(int)fh->type]; 00493 } 00494 if (fh->type == AST_FRAME_DTMF) { 00495 sprintf(subclass2, "%c", fh->csub); 00496 subclass = subclass2; 00497 } else if (fh->type == AST_FRAME_IAX) { 00498 if (fh->csub >= (int)sizeof(iaxs)/(int)sizeof(iaxs[0])) { 00499 snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub); 00500 subclass = subclass2; 00501 } else { 00502 subclass = iaxs[(int)fh->csub]; 00503 } 00504 } else if (fh->type == AST_FRAME_CONTROL) { 00505 if (fh->csub >= (int)sizeof(cmds)/(int)sizeof(cmds[0])) { 00506 snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub); 00507 subclass = subclass2; 00508 } else { 00509 subclass = cmds[(int)fh->csub]; 00510 } 00511 } else { 00512 snprintf(subclass2, sizeof(subclass2), "%d", fh->csub); 00513 subclass = subclass2; 00514 } 00515 snprintf(tmp, sizeof(tmp), 00516 "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s Subclass: %s\n", 00517 dir, 00518 retries, fh->oseqno, fh->iseqno, class, subclass); 00519 outputf(tmp); 00520 snprintf(tmp, sizeof(tmp), 00521 " Timestamp: %05lums SCall: %5.5d DCall: %5.5d [%s:%d]\n", 00522 (unsigned long)ntohl(fh->ts), 00523 ntohs(fh->scallno) & ~IAX_FLAG_FULL, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, 00524 ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port)); 00525 outputf(tmp); 00526 if (fh->type == AST_FRAME_IAX) 00527 dump_ies(fh->iedata, datalen); 00528 }
| static void internalerror | ( | const char * | str | ) | [static] |
| static void internaloutput | ( | const char * | str | ) | [static] |
void(* errorf)(const char *str) = internalerror [static] |
int frames = 0 [static] |
Referenced by dump_ies(), dundi_ie2str(), and iax_ie2str().
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] |
Referenced by dump_ies(), dundi_parse_ies(), dundi_set_output(), dundi_showframe(), iax_parse_ies(), iax_set_output(), and iax_showframe().
Definition at line 255 of file iax2-parser.c.
1.5.6