📄 iax2-parser.c
字号:
/* * Asterisk -- An open source telephony toolkit. * * Copyright (C) 1999 - 2005, Digium, Inc. * * Mark Spencer <markster@digium.com> * * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2. See the LICENSE file * at the top of the source tree. *//*! \file * * \brief Implementation of Inter-Asterisk eXchange Protocol, v 2 * * \author Mark Spencer <markster@digium.com> */#include "asterisk.h"ASTERISK_FILE_VERSION(__FILE__, "$Revision: 134814 $")#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"static int frames = 0;static int iframes = 0;static int oframes = 0;#if !defined(LOW_MEMORY)static void frame_cache_cleanup(void *data);/*! \brief A per-thread cache of iax_frame structures */AST_THREADSTORAGE_CUSTOM(frame_cache, frame_cache_init, frame_cache_cleanup);/*! \brief This is just so iax_frames, a list head struct for holding a list of * iax_frame structures, is defined. */AST_LIST_HEAD_NOLOCK(iax_frame_list, iax_frame);struct iax_frames { struct iax_frame_list list; size_t size;};#define FRAME_CACHE_MAX_SIZE 20#endifstatic void internaloutput(const char *str){ fputs(str, stdout);}static void internalerror(const char *str){ fprintf(stderr, "WARNING: %s", str);}static void (*outputf)(const char *str) = internaloutput;static void (*errorf)(const char *str) = internalerror;static void dump_addr(char *output, int maxlen, void *value, int len){ struct sockaddr_in sin; if (len == (int)sizeof(sin)) { memcpy(&sin, value, len); snprintf(output, maxlen, "IPV4 %s:%d", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); } else { snprintf(output, maxlen, "Invalid Address"); }}static void dump_string(char *output, int maxlen, void *value, int len){ maxlen--; if (maxlen > len) maxlen = len; strncpy(output, value, maxlen); output[maxlen] = '\0';}static void dump_prefs(char *output, int maxlen, void *value, int len){ struct ast_codec_pref pref; int total_len = 0; maxlen--; total_len = maxlen; if (maxlen > len) maxlen = len; strncpy(output, value, maxlen); output[maxlen] = '\0'; ast_codec_pref_convert(&pref, output, total_len, 0); memset(output,0,total_len); ast_codec_pref_string(&pref, output, total_len);}static void dump_int(char *output, int maxlen, void *value, int len){ if (len == (int)sizeof(unsigned int)) snprintf(output, maxlen, "%lu", (unsigned long)ntohl(get_unaligned_uint32(value))); else ast_copy_string(output, "Invalid INT", maxlen); }static void dump_short(char *output, int maxlen, void *value, int len){ if (len == (int)sizeof(unsigned short)) snprintf(output, maxlen, "%d", ntohs(get_unaligned_uint16(value))); else ast_copy_string(output, "Invalid SHORT", maxlen);}static void dump_byte(char *output, int maxlen, void *value, int len){ if (len == (int)sizeof(unsigned char)) snprintf(output, maxlen, "%d", *((unsigned char *)value)); else ast_copy_string(output, "Invalid BYTE", maxlen);}static void dump_datetime(char *output, int maxlen, void *value, int len){ struct tm tm; unsigned long val = (unsigned long) ntohl(get_unaligned_uint32(value)); if (len == (int)sizeof(unsigned int)) { tm.tm_sec = (val & 0x1f) << 1; tm.tm_min = (val >> 5) & 0x3f; tm.tm_hour = (val >> 11) & 0x1f; tm.tm_mday = (val >> 16) & 0x1f; tm.tm_mon = ((val >> 21) & 0x0f) - 1; tm.tm_year = ((val >> 25) & 0x7f) + 100; strftime(output, maxlen, "%Y-%m-%d %T", &tm); } else ast_copy_string(output, "Invalid DATETIME format!", maxlen);}static void dump_ipaddr(char *output, int maxlen, void *value, int len){ struct sockaddr_in sin; if (len == (int)sizeof(unsigned int)) { memcpy(&sin.sin_addr, value, len); snprintf(output, maxlen, "%s", ast_inet_ntoa(sin.sin_addr)); } else ast_copy_string(output, "Invalid IPADDR", maxlen);}static void dump_prov_flags(char *output, int maxlen, void *value, int len){ char buf[256] = ""; if (len == (int)sizeof(unsigned int)) snprintf(output, maxlen, "%lu (%s)", (unsigned long)ntohl(get_unaligned_uint32(value)), iax_provflags2str(buf, sizeof(buf), ntohl(get_unaligned_uint32(value)))); else ast_copy_string(output, "Invalid INT", maxlen);}static void dump_samprate(char *output, int maxlen, void *value, int len){ char tmp[256]=""; int sr; if (len == (int)sizeof(unsigned short)) { sr = ntohs(*((unsigned short *)value)); if (sr & IAX_RATE_8KHZ) strcat(tmp, ",8khz"); if (sr & IAX_RATE_11KHZ) strcat(tmp, ",11.025khz"); if (sr & IAX_RATE_16KHZ) strcat(tmp, ",16khz"); if (sr & IAX_RATE_22KHZ) strcat(tmp, ",22.05khz"); if (sr & IAX_RATE_44KHZ) strcat(tmp, ",44.1khz"); if (sr & IAX_RATE_48KHZ) strcat(tmp, ",48khz"); if (strlen(tmp)) ast_copy_string(output, &tmp[1], maxlen); else ast_copy_string(output, "None Specified!\n", maxlen); } else ast_copy_string(output, "Invalid SHORT", maxlen);}static void dump_prov_ies(char *output, int maxlen, unsigned char *iedata, int len);static void dump_prov(char *output, int maxlen, void *value, int len){ dump_prov_ies(output, maxlen, value, len);}static struct iax2_ie { int ie; char *name; void (*dump)(char *output, int maxlen, void *value, int len);} ies[] = { { IAX_IE_CALLED_NUMBER, "CALLED NUMBER", dump_string }, { IAX_IE_CALLING_NUMBER, "CALLING NUMBER", dump_string }, { IAX_IE_CALLING_ANI, "ANI", dump_string }, { IAX_IE_CALLING_NAME, "CALLING NAME", dump_string }, { IAX_IE_CALLED_CONTEXT, "CALLED CONTEXT", dump_string }, { IAX_IE_USERNAME, "USERNAME", dump_string }, { IAX_IE_PASSWORD, "PASSWORD", dump_string }, { IAX_IE_CAPABILITY, "CAPABILITY", dump_int }, { IAX_IE_FORMAT, "FORMAT", dump_int }, { IAX_IE_LANGUAGE, "LANGUAGE", dump_string }, { IAX_IE_VERSION, "VERSION", dump_short }, { IAX_IE_ADSICPE, "ADSICPE", dump_short }, { IAX_IE_DNID, "DNID", dump_string }, { IAX_IE_AUTHMETHODS, "AUTHMETHODS", dump_short }, { IAX_IE_CHALLENGE, "CHALLENGE", dump_string }, { IAX_IE_MD5_RESULT, "MD5 RESULT", dump_string }, { IAX_IE_RSA_RESULT, "RSA RESULT", dump_string }, { IAX_IE_APPARENT_ADDR, "APPARENT ADDRESS", dump_addr }, { IAX_IE_REFRESH, "REFRESH", dump_short }, { IAX_IE_DPSTATUS, "DIALPLAN STATUS", dump_short }, { IAX_IE_CALLNO, "CALL NUMBER", dump_short }, { IAX_IE_CAUSE, "CAUSE", dump_string }, { IAX_IE_IAX_UNKNOWN, "UNKNOWN IAX CMD", dump_byte }, { IAX_IE_MSGCOUNT, "MESSAGE COUNT", dump_short }, { IAX_IE_AUTOANSWER, "AUTO ANSWER REQ" }, { IAX_IE_TRANSFERID, "TRANSFER ID", dump_int }, { IAX_IE_RDNIS, "REFERRING DNIS", dump_string }, { IAX_IE_PROVISIONING, "PROVISIONING", dump_prov }, { IAX_IE_AESPROVISIONING, "AES PROVISIONG" }, { IAX_IE_DATETIME, "DATE TIME", dump_datetime }, { IAX_IE_DEVICETYPE, "DEVICE TYPE", dump_string }, { IAX_IE_SERVICEIDENT, "SERVICE IDENT", dump_string }, { IAX_IE_FIRMWAREVER, "FIRMWARE VER", dump_short }, { IAX_IE_FWBLOCKDESC, "FW BLOCK DESC", dump_int }, { IAX_IE_FWBLOCKDATA, "FW BLOCK DATA" }, { IAX_IE_PROVVER, "PROVISIONG VER", dump_int }, { IAX_IE_CALLINGPRES, "CALLING PRESNTN", dump_byte }, { IAX_IE_CALLINGTON, "CALLING TYPEOFNUM", dump_byte }, { IAX_IE_CALLINGTNS, "CALLING TRANSITNET", dump_short }, { IAX_IE_SAMPLINGRATE, "SAMPLINGRATE", dump_samprate }, { IAX_IE_CAUSECODE, "CAUSE CODE", dump_byte }, { IAX_IE_ENCRYPTION, "ENCRYPTION", dump_short }, { IAX_IE_ENCKEY, "ENCRYPTION KEY" }, { IAX_IE_CODEC_PREFS, "CODEC_PREFS", dump_prefs }, { IAX_IE_RR_JITTER, "RR_JITTER", dump_int }, { IAX_IE_RR_LOSS, "RR_LOSS", dump_int }, { IAX_IE_RR_PKTS, "RR_PKTS", dump_int }, { IAX_IE_RR_DELAY, "RR_DELAY", dump_short }, { IAX_IE_RR_DROPPED, "RR_DROPPED", dump_int }, { IAX_IE_RR_OOO, "RR_OUTOFORDER", dump_int },};static struct iax2_ie prov_ies[] = { { PROV_IE_USEDHCP, "USEDHCP" }, { PROV_IE_IPADDR, "IPADDR", dump_ipaddr }, { PROV_IE_SUBNET, "SUBNET", dump_ipaddr }, { PROV_IE_GATEWAY, "GATEWAY", dump_ipaddr }, { PROV_IE_PORTNO, "BINDPORT", dump_short }, { PROV_IE_USER, "USERNAME", dump_string }, { PROV_IE_PASS, "PASSWORD", dump_string }, { PROV_IE_LANG, "LANGUAGE", dump_string }, { PROV_IE_TOS, "TYPEOFSERVICE", dump_byte }, { PROV_IE_FLAGS, "FLAGS", dump_prov_flags }, { PROV_IE_FORMAT, "FORMAT", dump_int }, { PROV_IE_AESKEY, "AESKEY" }, { PROV_IE_SERVERIP, "SERVERIP", dump_ipaddr }, { PROV_IE_SERVERPORT, "SERVERPORT", dump_short }, { PROV_IE_NEWAESKEY, "NEWAESKEY" }, { PROV_IE_PROVVER, "PROV VERSION", dump_int }, { PROV_IE_ALTSERVER, "ALTSERVERIP", dump_ipaddr },};const char *iax_ie2str(int ie){ int x; for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) { if (ies[x].ie == ie) return ies[x].name; } return "Unknown IE";}static void dump_prov_ies(char *output, int maxlen, unsigned char *iedata, int len){ int ielen; int ie; int x; int found; char interp[80]; char tmp[256]; if (len < 2) return; strcpy(output, "\n"); maxlen -= strlen(output); output += strlen(output); while(len > 2) { ie = iedata[0]; ielen = iedata[1]; if (ielen + 2> len) { snprintf(tmp, (int)sizeof(tmp), "Total Prov IE length of %d bytes exceeds remaining prov frame length of %d bytes\n", ielen + 2, len); ast_copy_string(output, tmp, maxlen); maxlen -= strlen(output); output += strlen(output); return; } found = 0; for (x=0;x<(int)sizeof(prov_ies) / (int)sizeof(prov_ies[0]); x++) { if (prov_ies[x].ie == ie) { if (prov_ies[x].dump) { prov_ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen); snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", prov_ies[x].name, interp); ast_copy_string(output, tmp, maxlen); maxlen -= strlen(output); output += strlen(output); } else { if (ielen) snprintf(interp, (int)sizeof(interp), "%d bytes", ielen); else strcpy(interp, "Present"); snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", prov_ies[x].name, interp); ast_copy_string(output, tmp, maxlen); maxlen -= strlen(output); output += strlen(output); } found++; } } if (!found) { snprintf(tmp, (int)sizeof(tmp), " Unknown Prov IE %03d : Present\n", ie); ast_copy_string(output, tmp, maxlen); maxlen -= strlen(output); output += strlen(output); } iedata += (2 + ielen);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -