Fri Mar 14 07:00:01 CET 2003

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@644 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Matteo Brancaleoni
2003-03-14 06:00:20 +00:00
parent d9848d6c49
commit 2d86a6955c
4 changed files with 206 additions and 45 deletions

View File

@@ -25,11 +25,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <pthread.h> #include <pthread.h>
static char *tdesc = "Look up number from local blacklist database"; static char *tdesc = "Look up Caller*ID name/number from blacklist database";
static char *app = "LookupBlacklist"; static char *app = "LookupBlacklist";
static char *synopsis = "Look up number from local blacklist database"; static char *synopsis = "Look up Caller*ID name/number from blacklist database";
static char *descrip = static char *descrip =
" LookupBlacklist: Looks up the Caller*ID number on the active\n" " LookupBlacklist: Looks up the Caller*ID number on the active\n"
@@ -68,13 +68,13 @@ lookupblacklist_exec (struct ast_channel *chan, void *data)
if (!ast_db_get ("blacklist", shrunknum, blacklist, sizeof (blacklist))) if (!ast_db_get ("blacklist", shrunknum, blacklist, sizeof (blacklist)))
{ {
if (option_verbose > 2) if (option_verbose > 2)
ast_verbose (VERBOSE_PREFIX_3 "Blacklisted number %s found\n",shrunknum); ast_log(LOG_NOTICE, "Blacklisted number %s found\n",shrunknum);
bl = 1; bl = 1;
} }
else if (!ast_db_get ("blacklist", name, blacklist, sizeof (blacklist))) else if (!ast_db_get ("blacklist", name, blacklist, sizeof (blacklist)))
{ {
if (option_verbose > 2) if (option_verbose > 2)
ast_verbose (VERBOSE_PREFIX_3 "Blacklisted name \"%s\" found\n",name); ast_log (LOG_NOTICE,"Blacklisted name \"%s\" found\n",name);
bl = 1; bl = 1;
} }
} }

View File

@@ -30,6 +30,7 @@
#include <asterisk/acl.h> #include <asterisk/acl.h>
#include <asterisk/manager.h> #include <asterisk/manager.h>
#include <asterisk/callerid.h> #include <asterisk/callerid.h>
#include <asterisk/app.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
@@ -144,6 +145,7 @@ struct iax2_user {
char inkeys[80]; /* Key(s) this user can use to authenticate to us */ char inkeys[80]; /* Key(s) this user can use to authenticate to us */
int amaflags; int amaflags;
int hascallerid; int hascallerid;
int trunk; /* Treat with IAX2 trunking */
char callerid[AST_MAX_EXTENSION]; char callerid[AST_MAX_EXTENSION];
struct ast_ha *ha; struct ast_ha *ha;
struct iax2_context *contexts; struct iax2_context *contexts;
@@ -156,6 +158,7 @@ struct iax2_peer {
char secret[80]; char secret[80];
char outkey[80]; /* What key we use to talk to this peer */ char outkey[80]; /* What key we use to talk to this peer */
char context[AST_MAX_EXTENSION]; /* Default context (for transfer really) */ char context[AST_MAX_EXTENSION]; /* Default context (for transfer really) */
char mailbox[AST_MAX_EXTENSION]; /* Mailbox */
struct sockaddr_in addr; struct sockaddr_in addr;
int formats; int formats;
struct in_addr mask; struct in_addr mask;
@@ -176,6 +179,7 @@ struct iax2_peer {
int expirey; /* How soon to expire */ int expirey; /* How soon to expire */
int capability; /* Capability */ int capability; /* Capability */
int delme; /* I need to be deleted */ int delme; /* I need to be deleted */
int trunk; /* Treat as an IAX trunking */
/* Qualification */ /* Qualification */
int callno; /* Call number of POKE request */ int callno; /* Call number of POKE request */
@@ -209,6 +213,7 @@ struct iax2_registry {
int expire; /* Sched ID of expiration */ int expire; /* Sched ID of expiration */
int refresh; /* How often to refresh */ int refresh; /* How often to refresh */
int regstate; int regstate;
int messages; /* Message count */
int callno; /* Associated call number if applicable */ int callno; /* Associated call number if applicable */
struct sockaddr_in us; /* Who the server thinks we are */ struct sockaddr_in us; /* Who the server thinks we are */
struct iax2_registry *next; struct iax2_registry *next;
@@ -221,6 +226,8 @@ struct iax2_registry *registrations;
#define MAX_RETRY_TIME 10000 #define MAX_RETRY_TIME 10000
#define MAX_JITTER_BUFFER 50 #define MAX_JITTER_BUFFER 50
#define MAX_TRUNKDATA 640 /* 40ms, uncompressed linear */
/* If we have more than this much excess real jitter buffer, srhink it. */ /* If we have more than this much excess real jitter buffer, srhink it. */
static int max_jitter_buffer = MAX_JITTER_BUFFER; static int max_jitter_buffer = MAX_JITTER_BUFFER;
@@ -338,6 +345,11 @@ struct chan_iax2_pvt {
char dproot[AST_MAX_EXTENSION]; char dproot[AST_MAX_EXTENSION];
char accountcode[20]; char accountcode[20];
int amaflags; int amaflags;
/* This is part of a trunk interface */
int trunk;
/* Trunk data and length */
unsigned char trunkdata[MAX_TRUNKDATA];
unsigned int trunkdatalen;
struct iax2_dpcache *dpentries; struct iax2_dpcache *dpentries;
}; };
@@ -392,13 +404,13 @@ struct iax_ies {
char *called_context; char *called_context;
char *username; char *username;
char *password; char *password;
int capability; unsigned int capability;
int format; unsigned int format;
char *language; char *language;
int version; int version;
int adsicpe; unsigned short adsicpe;
char *dnid; char *dnid;
int authmethods; unsigned int authmethods;
char *challenge; char *challenge;
char *md5_result; char *md5_result;
char *rsa_result; char *rsa_result;
@@ -407,6 +419,8 @@ struct iax_ies {
unsigned short dpstatus; unsigned short dpstatus;
unsigned short callno; unsigned short callno;
char *cause; char *cause;
unsigned char iax_unknown;
int msgcount;
}; };
struct iax_ie_data { struct iax_ie_data {
@@ -462,32 +476,79 @@ static struct iax2_dpcache {
pthread_mutex_t dpcache_lock; pthread_mutex_t dpcache_lock;
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,value, maxlen);
output[maxlen] = '\0';
}
static void dump_int(char *output, int maxlen, void *value, int len)
{
if (len == sizeof(unsigned int))
snprintf(output, maxlen, "%d", ntohl(*((unsigned int *)value)));
else
snprintf(output, maxlen, "Invalid INT");
}
static void dump_short(char *output, int maxlen, void *value, int len)
{
if (len == sizeof(unsigned short))
snprintf(output, maxlen, "%d", ntohs(*((unsigned short *)value)));
else
snprintf(output, maxlen, "Invalid SHORT");
}
static void dump_byte(char *output, int maxlen, void *value, int len)
{
if (len == sizeof(unsigned char))
snprintf(output, maxlen, "%d", ntohs(*((unsigned char *)value)));
else
snprintf(output, maxlen, "Invalid BYTE");
}
static struct iax2_ie { static struct iax2_ie {
int ie; int ie;
char *name; char *name;
void (*dump)(char *output, int maxlen, void *value, int len);
} ies[] = { } ies[] = {
{ IAX_IE_CALLED_NUMBER, "CALLED NUMBER" }, { IAX_IE_CALLED_NUMBER, "CALLED NUMBER", dump_string },
{ IAX_IE_CALLING_NUMBER, "CALLING NUMBER" }, { IAX_IE_CALLING_NUMBER, "CALLING NUMBER", dump_string },
{ IAX_IE_CALLING_NUMBER, "ANI" }, { IAX_IE_CALLING_NUMBER, "ANI", dump_string },
{ IAX_IE_CALLING_NAME, "CALLING NAME" }, { IAX_IE_CALLING_NAME, "CALLING NAME", dump_string },
{ IAX_IE_CALLED_CONTEXT, "CALLED CONTEXT" }, { IAX_IE_CALLED_CONTEXT, "CALLED CONTEXT", dump_string },
{ IAX_IE_USERNAME, "USERNAME" }, { IAX_IE_USERNAME, "USERNAME", dump_string },
{ IAX_IE_PASSWORD, "PASSWORD" }, { IAX_IE_PASSWORD, "PASSWORD", dump_string },
{ IAX_IE_CAPABILITY, "CAPABILITY" }, { IAX_IE_CAPABILITY, "CAPABILITY", dump_int },
{ IAX_IE_FORMAT, "FORMAT" }, { IAX_IE_FORMAT, "FORMAT", dump_int },
{ IAX_IE_LANGUAGE, "LANGUAGE" }, { IAX_IE_LANGUAGE, "LANGUAGE", dump_string },
{ IAX_IE_VERSION, "VERSION" }, { IAX_IE_VERSION, "VERSION", dump_short },
{ IAX_IE_ADSICPE, "ADSICPE" }, { IAX_IE_ADSICPE, "ADSICPE", dump_short },
{ IAX_IE_DNID, "DNID" }, { IAX_IE_DNID, "DNID", dump_string },
{ IAX_IE_AUTHMETHODS, "AUTHMETHODS" }, { IAX_IE_AUTHMETHODS, "AUTHMETHODS", dump_int },
{ IAX_IE_CHALLENGE, "CHALLENGE" }, { IAX_IE_CHALLENGE, "CHALLENGE", dump_string },
{ IAX_IE_MD5_RESULT, "MD5 RESULT" }, { IAX_IE_MD5_RESULT, "MD5 RESULT", dump_string },
{ IAX_IE_RSA_RESULT, "RSA RESULT" }, { IAX_IE_RSA_RESULT, "RSA RESULT", dump_string },
{ IAX_IE_APPARENT_ADDR, "APPARENT ADDRESS" }, { IAX_IE_APPARENT_ADDR, "APPARENT ADDRESS", dump_addr },
{ IAX_IE_REFRESH, "REFRESH" }, { IAX_IE_REFRESH, "REFRESH", dump_short },
{ IAX_IE_DPSTATUS, "DIALPLAN STATUS" }, { IAX_IE_DPSTATUS, "DIALPLAN STATUS", dump_short },
{ IAX_IE_CALLNO, "CALL NUMBER" }, { IAX_IE_CALLNO, "CALL NUMBER", dump_short },
{ IAX_IE_CAUSE, "CAUSE" }, { IAX_IE_CAUSE, "CAUSE", dump_string },
{ IAX_IE_IAX_UNKNOWN, "UNKNOWN IAX CMD", dump_byte },
{ IAX_IE_MSGCOUNT, "MESSAGE COUNT", dump_short },
}; };
static char *ie2str(int ie) static char *ie2str(int ie)
@@ -500,8 +561,44 @@ static char *ie2str(int ie)
return "Unknown IE"; return "Unknown IE";
} }
static void dump_ies(unsigned char *iedata, int len)
{
int ielen;
int ie;
int x;
int found;
char interp[80];
if (len < 2)
return;
while(len > 2) {
ie = iedata[0];
ielen = iedata[1];
if (ielen + 2> len) {
ast_verbose("Total IE length of %d bytes exceeds remaining frame length of %d bytes\n", ielen + 2, len);
return;
}
found = 0;
for (x=0;x<sizeof(ies) / sizeof(ies[0]); x++) {
if (ies[x].ie == ie) {
if (ies[x].dump) {
ies[x].dump(interp, sizeof(interp), iedata + 2, ielen);
ast_verbose(" %-15.15s : %s\n", ies[x].name, interp);
} else {
ast_verbose(" %-15.15s : Present\n", ies[x].name);
}
found++;
}
}
if (!found)
ast_verbose(" Unknown IE %d : Present\n", ie);
iedata += (2 + ielen);
len -= (2 + ielen);
}
ast_verbose("\n");
}
#ifdef DEBUG_SUPPORT #ifdef DEBUG_SUPPORT
void showframe(struct ast_iax2_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin) void showframe(struct ast_iax2_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
{ {
char *frames[] = { char *frames[] = {
"(0?)", "(0?)",
@@ -614,6 +711,8 @@ void showframe(struct ast_iax2_frame *f, struct ast_iax2_full_hdr *fhi, int rx,
ntohl(fh->ts), ntohl(fh->ts),
ntohs(fh->scallno) & ~AST_FLAG_FULL, ntohs(fh->dcallno) & ~AST_FLAG_RETRANS, ntohs(fh->scallno) & ~AST_FLAG_FULL, ntohs(fh->dcallno) & ~AST_FLAG_RETRANS,
inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
if (fh->type == AST_FRAME_IAX)
dump_ies(fh->iedata, datalen);
} }
#endif #endif
@@ -1009,14 +1108,14 @@ static int send_packet(struct ast_iax2_frame *f)
if (f->transfer) { if (f->transfer) {
#ifdef DEBUG_SUPPORT #ifdef DEBUG_SUPPORT
if (iaxdebug) if (iaxdebug)
showframe(f, NULL, 0, &iaxs[f->callno]->transfer); showframe(f, NULL, 0, &iaxs[f->callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
#endif #endif
res = sendto(netsocket, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->transfer, res = sendto(netsocket, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->transfer,
sizeof(iaxs[f->callno]->transfer)); sizeof(iaxs[f->callno]->transfer));
} else { } else {
#ifdef DEBUG_SUPPORT #ifdef DEBUG_SUPPORT
if (iaxdebug) if (iaxdebug)
showframe(f, NULL, 0, &iaxs[f->callno]->addr); showframe(f, NULL, 0, &iaxs[f->callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
#endif #endif
res = sendto(netsocket, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->addr, res = sendto(netsocket, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->addr,
sizeof(iaxs[f->callno]->addr)); sizeof(iaxs[f->callno]->addr));
@@ -1691,6 +1790,11 @@ static int iax_ie_append_str(struct iax_ie_data *ied, unsigned char ie, unsigned
return iax_ie_append_raw(ied, ie, str, strlen(str)); return iax_ie_append_raw(ied, ie, str, strlen(str));
} }
static int iax_ie_append_byte(struct iax_ie_data *ied, unsigned char ie, unsigned char dat)
{
return iax_ie_append_raw(ied, ie, &dat, 1);
}
static int iax2_call(struct ast_channel *c, char *dest, int timeout) static int iax2_call(struct ast_channel *c, char *dest, int timeout)
{ {
struct sockaddr_in sin; struct sockaddr_in sin;
@@ -1796,7 +1900,7 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout)
} }
iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
iax_ie_append_int(&ied, IAX_IE_CAPABILITY, p->capability); iax_ie_append_int(&ied, IAX_IE_CAPABILITY, p->capability);
iax_ie_append_int(&ied, IAX_IE_ADSICPE, c->adsicpe); iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
/* Transmit the string in a "NEW" request */ /* Transmit the string in a "NEW" request */
#if 0 #if 0
/* XXX We have no equivalent XXX */ /* XXX We have no equivalent XXX */
@@ -2699,11 +2803,13 @@ static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
strncpy(md5secret, ies->md5_result, sizeof(md5secret)-1); strncpy(md5secret, ies->md5_result, sizeof(md5secret)-1);
if (ies->rsa_result) if (ies->rsa_result)
strncpy(rsasecret, ies->rsa_result, sizeof(rsasecret)-1); strncpy(rsasecret, ies->rsa_result, sizeof(rsasecret)-1);
printf("Auth methods: %d, rsasecret: %s, inkeys: %s\n", p->authmethods, rsasecret, p->inkeys);
if ((p->authmethods & IAX_AUTH_RSA) && strlen(rsasecret) && strlen(p->inkeys)) { if ((p->authmethods & IAX_AUTH_RSA) && strlen(rsasecret) && strlen(p->inkeys)) {
struct ast_key *key; struct ast_key *key;
char *keyn; char *keyn;
char tmpkey[256]; char tmpkey[256];
char *stringp=NULL; char *stringp=NULL;
printf("Checking RSA methods\n");
strncpy(tmpkey, p->inkeys, sizeof(tmpkey)); strncpy(tmpkey, p->inkeys, sizeof(tmpkey));
stringp=tmpkey; stringp=tmpkey;
keyn = strsep(&stringp, ":"); keyn = strsep(&stringp, ":");
@@ -3080,10 +3186,12 @@ static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int c
struct iax2_registry *reg; struct iax2_registry *reg;
/* Start pessimistic */ /* Start pessimistic */
char peer[256] = ""; char peer[256] = "";
char msgstatus[40] = "";
int refresh = 0; int refresh = 0;
char ourip[256] = "<Unspecified>"; char ourip[256] = "<Unspecified>";
struct sockaddr_in oldus; struct sockaddr_in oldus;
struct sockaddr_in us; struct sockaddr_in us;
int oldmsgs;
memset(&us, 0, sizeof(us)); memset(&us, 0, sizeof(us));
if (ies->apparent_addr) if (ies->apparent_addr)
@@ -3101,11 +3209,13 @@ static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int c
return -1; return -1;
} }
memcpy(&oldus, &reg->us, sizeof(oldus)); memcpy(&oldus, &reg->us, sizeof(oldus));
oldmsgs = reg->messages;
if (memcmp(&reg->addr, sin, sizeof(&reg->addr))) { if (memcmp(&reg->addr, sin, sizeof(&reg->addr))) {
ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", inet_ntoa(sin->sin_addr)); ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", inet_ntoa(sin->sin_addr));
return -1; return -1;
} }
memcpy(&reg->us, &us, sizeof(reg->us)); memcpy(&reg->us, &us, sizeof(reg->us));
reg->messages = ies->msgcount - 1;
if (refresh && (reg->refresh < refresh)) { if (refresh && (reg->refresh < refresh)) {
/* Refresh faster if necessary */ /* Refresh faster if necessary */
reg->refresh = refresh; reg->refresh = refresh;
@@ -3113,9 +3223,17 @@ static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int c
ast_sched_del(sched, reg->expire); ast_sched_del(sched, reg->expire);
reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
} }
if (memcmp(&oldus, &reg->us, sizeof(oldus)) && (option_verbose > 2)) { if ((memcmp(&oldus, &reg->us, sizeof(oldus)) || (reg->messages != oldmsgs)) && (option_verbose > 2)) {
if (reg->messages > 65534)
snprintf(msgstatus, sizeof(msgstatus), " with message(s) waiting\n");
else if (reg->messages > 1)
snprintf(msgstatus, sizeof(msgstatus), " with %d messages waiting\n", reg->messages);
else if (reg->messages > 0)
snprintf(msgstatus, sizeof(msgstatus), " with 1 message waiting\n");
else if (reg->messages > -1)
snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
snprintf(ourip, sizeof(ourip), "%s:%d", inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); snprintf(ourip, sizeof(ourip), "%s:%d", inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
ast_verbose(VERBOSE_PREFIX_3 "Registered to '%s', who sees us as %s\n", inet_ntoa(sin->sin_addr), ourip); ast_verbose(VERBOSE_PREFIX_3 "Registered to '%s', who sees us as %s%s\n", inet_ntoa(sin->sin_addr), ourip, msgstatus);
} }
reg->regstate = REG_STATE_REGISTERED; reg->regstate = REG_STATE_REGISTERED;
return 0; return 0;
@@ -3200,6 +3318,7 @@ static int update_registry(char *name, struct sockaddr_in *sin, int callno)
/* Called from IAX thread only, with proper iaxsl lock */ /* Called from IAX thread only, with proper iaxsl lock */
struct iax_ie_data ied; struct iax_ie_data ied;
struct iax2_peer *p; struct iax2_peer *p;
int msgcount;
memset(&ied, 0, sizeof(ied)); memset(&ied, 0, sizeof(ied));
for (p = peerl.peers;p;p = p->next) { for (p = peerl.peers;p;p = p->next) {
if (!strcasecmp(name, p->name)) { if (!strcasecmp(name, p->name)) {
@@ -3220,6 +3339,12 @@ static int update_registry(char *name, struct sockaddr_in *sin, int callno)
iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expirey); iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expirey);
iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
if (strlen(p->mailbox)) {
msgcount = ast_app_has_voicemail(p->mailbox);
if (msgcount)
msgcount = 65535;
iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
}
if (p->hascallerid) if (p->hascallerid)
iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->callerid); iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->callerid);
return send_command_final(iaxs[callno], AST_FRAME_IAX, AST_IAX2_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);; return send_command_final(iaxs[callno], AST_FRAME_IAX, AST_IAX2_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);;
@@ -3382,7 +3507,6 @@ static int parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
ast_log(LOG_WARNING, "Information element length exceeds message size\n"); ast_log(LOG_WARNING, "Information element length exceeds message size\n");
return -1; return -1;
} }
ast_log(LOG_DEBUG, "IE '%s' (%d) of length %d\n", ie2str(ie), ie, len);
switch(ie) { switch(ie) {
case IAX_IE_CALLED_NUMBER: case IAX_IE_CALLED_NUMBER:
ies->called_number = data + 2; ies->called_number = data + 2;
@@ -3427,10 +3551,10 @@ static int parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
ies->version = ntohs(*((unsigned short *)(data + 2))); ies->version = ntohs(*((unsigned short *)(data + 2)));
break; break;
case IAX_IE_ADSICPE: case IAX_IE_ADSICPE:
if (len != sizeof(unsigned int)) if (len != sizeof(unsigned short))
ast_log(LOG_WARNING, "Expecting adsicpe to be %d bytes long but was %d\n", sizeof(unsigned int), len); ast_log(LOG_WARNING, "Expecting adsicpe to be %d bytes long but was %d\n", sizeof(unsigned short), len);
else else
ies->adsicpe = ntohl(*((unsigned int *)(data + 2))); ies->adsicpe = ntohs(*((unsigned short *)(data + 2)));
break; break;
case IAX_IE_DNID: case IAX_IE_DNID:
ies->dnid = data + 2; ies->dnid = data + 2;
@@ -3448,7 +3572,7 @@ static int parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
ies->md5_result = data + 2; ies->md5_result = data + 2;
break; break;
case IAX_IE_RSA_RESULT: case IAX_IE_RSA_RESULT:
ies->md5_result = data + 2; ies->rsa_result = data + 2;
break; break;
case IAX_IE_APPARENT_ADDR: case IAX_IE_APPARENT_ADDR:
ies->apparent_addr = ((struct sockaddr_in *)(data + 2)); ies->apparent_addr = ((struct sockaddr_in *)(data + 2));
@@ -3474,6 +3598,18 @@ static int parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
case IAX_IE_CAUSE: case IAX_IE_CAUSE:
ies->cause = data + 2; ies->cause = data + 2;
break; break;
case IAX_IE_IAX_UNKNOWN:
if (len == 1)
ies->iax_unknown = data[2];
else
ast_log(LOG_WARNING, "Expected single byte Unknown command, but was %d long\n", len);
break;
case IAX_IE_MSGCOUNT:
if (len != sizeof(unsigned short))
ast_log(LOG_WARNING, "Expecting msgcount to be %d bytes long but was %d\n", sizeof(unsigned short), len);
else
ies->msgcount = ntohs(*((unsigned short *)(data + 2))) + 1; /* Add 1 to know if we got it */
break;
default: default:
ast_log(LOG_NOTICE, "Ignoring unknown information element '%s' (%d) of length %d\n", ie2str(ie), ie, len); ast_log(LOG_NOTICE, "Ignoring unknown information element '%s' (%d) of length %d\n", ie2str(ie), ie, len);
} }
@@ -3482,6 +3618,8 @@ static int parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
datalen -= (len + 2); datalen -= (len + 2);
data += (len + 2); data += (len + 2);
} }
/* Null-terminate last field */
*data = '\0';
if (datalen) { if (datalen) {
ast_log(LOG_WARNING, "Invalid information element contents, strange boundary\n"); ast_log(LOG_WARNING, "Invalid information element contents, strange boundary\n");
return -1; return -1;
@@ -3530,7 +3668,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
} }
#ifdef DEBUG_SUPPORT #ifdef DEBUG_SUPPORT
if (iaxdebug) if (iaxdebug)
showframe(NULL, fh, 1, &sin); showframe(NULL, fh, 1, &sin, res - sizeof(struct ast_iax2_full_hdr));
#endif #endif
if (ntohs(mh->callno) & AST_FLAG_FULL) { if (ntohs(mh->callno) & AST_FLAG_FULL) {
/* Get the destination call number */ /* Get the destination call number */
@@ -4181,8 +4319,14 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
case AST_IAX2_COMMAND_DPREP: case AST_IAX2_COMMAND_DPREP:
complete_dpreply(iaxs[fr.callno], &ies); complete_dpreply(iaxs[fr.callno], &ies);
break; break;
case AST_IAX2_COMMAND_UNSUPPORT:
ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
break;
default: default:
ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr.callno, iaxs[fr.callno]->peercallno); ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr.callno, iaxs[fr.callno]->peercallno);
memset(&ied0, 0, sizeof(ied0));
iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
send_command(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX2_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
} }
/* Don't actually pass these frames along */ /* Don't actually pass these frames along */
if ((f.subclass != AST_IAX2_COMMAND_ACK) && if ((f.subclass != AST_IAX2_COMMAND_ACK) &&
@@ -4265,7 +4409,7 @@ static int iax2_do_register(struct iax2_registry *reg)
struct iax_ie_data ied; struct iax_ie_data ied;
if (option_debug) if (option_debug)
ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
if (reg->callno < 0) { if (!reg->callno) {
if (option_debug) if (option_debug)
ast_log(LOG_DEBUG, "Allocate call number\n"); ast_log(LOG_DEBUG, "Allocate call number\n");
reg->callno = find_callno(0, 0, &reg->addr, NEW_FORCE); reg->callno = find_callno(0, 0, &reg->addr, NEW_FORCE);
@@ -4528,6 +4672,10 @@ static struct iax2_peer *build_peer(char *name, struct ast_variable *v)
while(v) { while(v) {
if (!strcasecmp(v->name, "secret")) if (!strcasecmp(v->name, "secret"))
strncpy(peer->secret, v->value, sizeof(peer->secret)-1); strncpy(peer->secret, v->value, sizeof(peer->secret)-1);
else if (!strcasecmp(v->name, "mailbox"))
strncpy(peer->mailbox, v->value, sizeof(peer->mailbox) - 1);
else if (!strcasecmp(v->name, "trunk"))
peer->trunk = 1;
else if (!strcasecmp(v->name, "auth")) { else if (!strcasecmp(v->name, "auth")) {
peer->authmethods = get_auth_methods(v->value); peer->authmethods = get_auth_methods(v->value);
} else if (!strcasecmp(v->name, "host")) { } else if (!strcasecmp(v->name, "host")) {
@@ -4645,6 +4793,8 @@ static struct iax2_user *build_user(char *name, struct ast_variable *v)
user->authmethods = get_auth_methods(v->value); user->authmethods = get_auth_methods(v->value);
} else if (!strcasecmp(v->name, "secret")) { } else if (!strcasecmp(v->name, "secret")) {
strncpy(user->secret, v->value, sizeof(user->secret)-1); strncpy(user->secret, v->value, sizeof(user->secret)-1);
} else if (!strcasecmp(v->name, "trunk")) {
user->trunk = 1;
} else if (!strcasecmp(v->name, "callerid")) { } else if (!strcasecmp(v->name, "callerid")) {
strncpy(user->callerid, v->value, sizeof(user->callerid)-1); strncpy(user->callerid, v->value, sizeof(user->callerid)-1);
user->hascallerid=1; user->hascallerid=1;

View File

@@ -80,7 +80,7 @@
#define IAX_IE_FORMAT 9 /* Desired codec format - unsigned int */ #define IAX_IE_FORMAT 9 /* Desired codec format - unsigned int */
#define IAX_IE_LANGUAGE 10 /* Desired language - string */ #define IAX_IE_LANGUAGE 10 /* Desired language - string */
#define IAX_IE_VERSION 11 /* Protocol version - short */ #define IAX_IE_VERSION 11 /* Protocol version - short */
#define IAX_IE_ADSICPE 12 /* CPE ADSI capability - int */ #define IAX_IE_ADSICPE 12 /* CPE ADSI capability - short */
#define IAX_IE_DNID 13 /* Originally dialed DNID - string */ #define IAX_IE_DNID 13 /* Originally dialed DNID - string */
#define IAX_IE_AUTHMETHODS 14 /* Authentication method(s) - short */ #define IAX_IE_AUTHMETHODS 14 /* Authentication method(s) - short */
#define IAX_IE_CHALLENGE 15 /* Challenge data for MD5/RSA - string */ #define IAX_IE_CHALLENGE 15 /* Challenge data for MD5/RSA - string */
@@ -91,6 +91,8 @@
#define IAX_IE_DPSTATUS 20 /* Dialplan status - short */ #define IAX_IE_DPSTATUS 20 /* Dialplan status - short */
#define IAX_IE_CALLNO 21 /* Call number of peer - short */ #define IAX_IE_CALLNO 21 /* Call number of peer - short */
#define IAX_IE_CAUSE 22 /* Cause - string */ #define IAX_IE_CAUSE 22 /* Cause - string */
#define IAX_IE_IAX_UNKNOWN 23 /* Unknown IAX command - byte */
#define IAX_IE_MSGCOUNT 24 /* How many messages waiting - short */
#define IAX_AUTH_PLAINTEXT (1 << 0) #define IAX_AUTH_PLAINTEXT (1 << 0)
#define IAX_AUTH_MD5 (1 << 1) #define IAX_AUTH_MD5 (1 << 1)
@@ -123,7 +125,7 @@ struct ast_iax2_mini_hdr {
unsigned short ts; /* 16-bit Timestamp (high 16 bits from last ast_iax2_full_hdr) */ unsigned short ts; /* 16-bit Timestamp (high 16 bits from last ast_iax2_full_hdr) */
/* Frametype implicitly VOICE_FRAME */ /* Frametype implicitly VOICE_FRAME */
/* subclass implicit from last ast_iax2_full_hdr */ /* subclass implicit from last ast_iax2_full_hdr */
unsigned char iedata[0]; unsigned char data[0];
} __attribute__ ((__packed__)); } __attribute__ ((__packed__));
struct ast_iax2_meta_hdr { struct ast_iax2_meta_hdr {

View File

@@ -157,11 +157,20 @@ host=216.207.245.47
;[dynamichost] ;[dynamichost]
;host=dynamic ;host=dynamic
;secret=mysecret ;secret=mysecret
;mailbox=1234 ; Notify about mailbox 1234
;inkeys=key1:key2 ;inkeys=key1:key2
;defaultip=216.207.245.34 ;defaultip=216.207.245.34
;callerid="Some Host" <(256) 428-6011> ;callerid="Some Host" <(256) 428-6011>
; ;
;
;[biggateway]
;type=peer
;host=192.168.0.1
;secret=myscret
;trunk=yes ; Use IAX2 trunking with this host
;
; ;
; Friends are a short cut for creating a user and ; Friends are a short cut for creating a user and
; a peer with the same values. ; a peer with the same values.