diff options
Diffstat (limited to 'channels/iax2-parser.c')
-rwxr-xr-x | channels/iax2-parser.c | 112 |
1 files changed, 108 insertions, 4 deletions
diff --git a/channels/iax2-parser.c b/channels/iax2-parser.c index e41056eaf..40b2e2793 100755 --- a/channels/iax2-parser.c +++ b/channels/iax2-parser.c @@ -23,6 +23,7 @@ #include <stdio.h> #include "iax2.h" #include "iax2-parser.h" +#include "iax2-provision.h" static int frames = 0; @@ -82,11 +83,40 @@ static void dump_short(char *output, int maxlen, void *value, int len) static void dump_byte(char *output, int maxlen, void *value, int len) { if (len == (int)sizeof(unsigned char)) - snprintf(output, maxlen, "%d", ntohs(*((unsigned char *)value))); + snprintf(output, maxlen, "%d", *((unsigned char *)value)); else snprintf(output, maxlen, "Invalid BYTE"); } +static void dump_ipaddr(char *output, int maxlen, void *value, int len) +{ + struct sockaddr_in sin; + char iabuf[INET_ADDRSTRLEN]; + if (len == (int)sizeof(unsigned int)) { + memcpy(&sin.sin_addr, value, len); + ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr); + snprintf(output, maxlen, "%s", iabuf); + } else + snprintf(output, maxlen, "Invalid IPADDR"); +} + + +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(*((unsigned int *)value)), + iax_provflags2str(buf, sizeof(buf), ntohl(*((unsigned int *)value)))); + else + snprintf(output, maxlen, "Invalid INT"); +} + +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; @@ -119,7 +149,7 @@ static struct iax2_ie { { IAX_IE_AUTOANSWER, "AUTO ANSWER REQ" }, { IAX_IE_TRANSFERID, "TRANSFER ID", dump_int }, { IAX_IE_RDNIS, "REFERRING DNIS", dump_string }, - { IAX_IE_PROVISIONING, "PROVISIONING" }, + { 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 }, @@ -130,6 +160,26 @@ static struct iax2_ie { { IAX_IE_PROVVER, "PROVISIONG VER", 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_SERVERUSER, "USERNAME", dump_string }, + { PROV_IE_SERVERPASS, "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; @@ -140,7 +190,8 @@ const char *iax_ie2str(int ie) return "Unknown IE"; } -static void dump_ies(unsigned char *iedata, int len) + +static void dump_prov_ies(char *output, int maxlen, unsigned char *iedata, int len) { int ielen; int ie; @@ -150,6 +201,57 @@ static void dump_ies(unsigned char *iedata, int len) 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); + strncpy(output, tmp, maxlen - 1); + 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); + strncpy(output, tmp, maxlen - 1); + 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); + strncpy(output, tmp, maxlen - 1); + maxlen -= strlen(output); output += strlen(output); + } + found++; + } + } + if (!found) { + snprintf(tmp, (int)sizeof(tmp), " Unknown Prov IE %03d : Present\n", ie); + strncpy(output, tmp, maxlen - 1); + maxlen -= 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]; @@ -551,8 +653,10 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen) if (len != (int)sizeof(unsigned int)) { snprintf(tmp, (int)sizeof(tmp), "Expected provisioning version to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); errorf(tmp); - } else + } else { + ies->provverpres = 1; ies->provver = ntohl(*((unsigned int *)(data + 2))); + } break; default: snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len); |