⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iax2-parser.c

📁 来自网络的iaxclient的协议栈源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Asterisk -- A telephony toolkit for Linux. * * Implementation of Inter-Asterisk eXchange *  * Copyright (C) 2003-2004, Digium * * Mark Spencer <markster@digium.com> * * This program is free software, distributed under the terms of * the GNU Lesser (Library) General Public License */#if defined(WIN32)  ||  defined(_WIN32_WCE)#include <winsock.h>#define snprintf _snprintf#else#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#endif#ifndef _MSC_VER#include <unistd.h>#endif#include <string.h>#include <stdlib.h>#include <stdio.h>#include "frame.h"#include "iax2.h"#include "iax2-parser.h"static int frames = 0;static int iframes = 0;static int oframes = 0;#ifdef ALIGN32static unsigned int get_uint32(unsigned char *p){  return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];}static unsigned short get_uint16(unsigned char *p){  return (p[0] << 8) | p[1] ;}#else#define get_uint32(p) (*((unsigned int *)(p)))#define get_uint16(p) (*((unsigned short *)(p)))#endifstatic void internaloutput(const char *str){	printf(str);}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 == sizeof(sin)) {		memcpy(&sin, value, len);		snprintf(output, maxlen, "IPV4 %s:%d", 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,(const char *)value, maxlen);	output[maxlen] = '\0';}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_uint32(value)));	else		snprintf(output, maxlen, "Invalid INT");}static void dump_short(char *output, int maxlen, void *value, int len){	if (len == (int)sizeof(unsigned short))		snprintf(output, maxlen, "%d", ntohs(get_uint16(value)));	else		snprintf(output, maxlen, "Invalid SHORT");}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		snprintf(output, maxlen, "Invalid BYTE");}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))			strncpy(output, &tmp[1], maxlen - 1);		else			strncpy(output, "None specified!\n", maxlen - 1);	} else		snprintf(output, maxlen, "Invalid SHORT");}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, (unsigned char *)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_CODEC_PREFS, "CODEC_PREFS", 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_int },	{ 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_CODEC_PREFS, "CODEC_PREFS", dump_string },	{ 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_OOO", dump_int },};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 found;	char tmp[256];	if (len < 2)		return;	strcpy(output, "\n"); 	maxlen -= (int)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);			strncpy(output, tmp, maxlen - 1);			maxlen -= (int)strlen(output); output += strlen(output);			return;		}		found = 0;		if (!found) {			snprintf(tmp, (int)sizeof(tmp), "       Unknown Prov IE %03d  : Present\n", ie);			strncpy(output, tmp, maxlen - 1);			maxlen -= (int)strlen(output); output += strlen(output);		}		iedata += (2 + ielen);		len -= (2 + ielen);	}}static void dump_ies(unsigned char *iedata, int len){	int ielen;	int ie;	int x;	int found;	char interp[1024];	char tmp[1024];	if (len < 2)		return;	while(len > 2) {		ie = iedata[0];		ielen = iedata[1];		if (ielen + 2> len) {			snprintf(tmp, (int)sizeof(tmp), "Total IE length of %d bytes exceeds remaining frame length of %d bytes\n", ielen + 2, len);			outputf(tmp);			return;		}		found = 0;		for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {			if (ies[x].ie == ie) {				if (ies[x].dump) {					ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen);					snprintf(tmp, (int)sizeof(tmp), "   %-15.15s : %s\n", ies[x].name, interp);					outputf(tmp);				} else {					if (ielen)						snprintf(interp, (int)sizeof(interp), "%d bytes", ielen);					else						strcpy(interp, "Present");					snprintf(tmp, (int)sizeof(tmp), "   %-15.15s : %s\n", ies[x].name, interp);					outputf(tmp);				}				found++;			}		}		if (!found) {			snprintf(tmp, (int)sizeof(tmp), "   Unknown IE %03d  : Present\n", ie);			outputf(tmp);		}		iedata += (2 + ielen);		len -= (2 + ielen);	}	outputf("\n");}void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen){	const char *frames[] = {		"(0?)",		"DTMF   ",		"VOICE  ",		"VIDEO  ",		"CONTROL",		"NULL   ",		"IAX    ",		"TEXT   ",		"IMAGE  " };	const char *iaxs[] = {		"(0?)",		"NEW    ",		"PING   ",		"PONG   ",		"ACK    ",		"HANGUP ",		"REJECT ",		"ACCEPT ",		"AUTHREQ",		"AUTHREP",		"INVAL  ",		"LAGRQ  ",		"LAGRP  ",		"REGREQ ",		"REGAUTH",		"REGACK ",		"REGREJ ",		"REGREL ",		"VNAK   ",		"DPREQ  ",		"DPREP  ",		"DIAL   ",		"TXREQ  ",		"TXCNT  ",		"TXACC  ",		"TXREADY",		"TXREL  ",		"TXREJ  ",		"QUELCH ",		"UNQULCH",		"POKE",		"PAGE",		"MWI",		"UNSUPPORTED",		"TRANSFER",		"PROVISION",		"FWDOWNLD",		"FWDATA"	};	const char *cmds[] = {		"(0?)",		"HANGUP ",		"RING   ",		"RINGING",		"ANSWER ",		"BUSY   ",		"TKOFFHK ",		"OFFHOOK" };	struct ast_iax2_full_hdr *fh;	char retries[20];	char class2[20];	char subclass2[20];	const char *clas;	const char *subclass;	char tmp[256];	if (f) {		fh = (struct ast_iax2_full_hdr *)f->data;		snprintf(retries, (int)sizeof(retries), "%03d", f->retries);	} else {		fh = fhi;		if (ntohs(fh->dcallno) & IAX_FLAG_RETRANS)			strcpy(retries, "Yes");		else			strcpy(retries, " No");	}	if (!(ntohs(fh->scallno) & IAX_FLAG_FULL)) {		/* Don't mess with mini-frames */		return;	}	if (fh->type > (int)sizeof(frames)/(int)sizeof(char *)) {		snprintf(class2, (int)sizeof(class2), "(%d?)", fh->type);		clas = class2;	} else {		clas = frames[(int)fh->type];	}	if (fh->type == AST_FRAME_DTMF) {		sprintf(subclass2, "%c", fh->csub);		subclass = subclass2;	} else if (fh->type == AST_FRAME_IAX) {		if (fh->csub >= (int)sizeof(iaxs)/(int)sizeof(iaxs[0])) {			snprintf(subclass2, (int)sizeof(subclass2), "(%d?)", fh->csub);			subclass = subclass2;		} else {			subclass = iaxs[(int)fh->csub];		}	} else if (fh->type == AST_FRAME_CONTROL) {		if (fh->csub > (int)sizeof(cmds)/(int)sizeof(char *)) {			snprintf(subclass2, (int)sizeof(subclass2), "(%d?)", fh->csub);			subclass = subclass2;		} else {			subclass = cmds[(int)fh->csub];		}	} else {		snprintf(subclass2, (int)sizeof(subclass2), "%d", fh->csub);		subclass = subclass2;	}snprintf(tmp, (int)sizeof(tmp), "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s Subclass: %s\n",	(rx ? "Rx" : "Tx"),	retries, fh->oseqno, fh->iseqno, clas, subclass);	outputf(tmp);snprintf(tmp, (int)sizeof(tmp), "   Timestamp: %05lums  SCall: %5.5d  DCall: %5.5d [%s:%d]\n",	(unsigned long)ntohl(fh->ts),	ntohs(fh->scallno) & ~IAX_FLAG_FULL, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS,		inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));	outputf(tmp);	if (fh->type == AST_FRAME_IAX)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -