Wed Oct 28 11:52:19 2009

Asterisk developer's documentation


dundi-parser.c File Reference

Distributed Universal Number Discovery (DUNDi). More...

#include "asterisk.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "asterisk/frame.h"
#include "asterisk/utils.h"
#include "asterisk/dundi.h"
#include "dundi-parser.h"

Include dependency graph for dundi-parser.c:

Go to the source code of this file.

Data Structures

struct  dundi_ie

Functions

static void dump_answer (char *output, int maxlen, void *value, int len)
static void dump_byte (char *output, int maxlen, void *value, int len)
static void dump_cause (char *output, int maxlen, void *value, int len)
static void dump_cbypass (char *output, int maxlen, void *value, int len)
static void dump_eid (char *output, int maxlen, void *value, int len)
static void dump_encrypted (char *output, int maxlen, void *value, int len)
static void dump_hint (char *output, int maxlen, void *value, int len)
static void dump_ies (unsigned char *iedata, int spaces, int len)
static void dump_int (char *output, int maxlen, void *value, int len)
static void dump_raw (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)
char * dundi_eid_to_str_short (char *s, int maxlen, dundi_eid *eid)
int dundi_eid_zero (dundi_eid *eid)
char * dundi_flags2str (char *buf, int bufsiz, int flags)
char * dundi_hint2str (char *buf, int bufsiz, int flags)
const char * dundi_ie2str (int ie)
int dundi_ie_append (struct dundi_ie_data *ied, unsigned char ie)
int dundi_ie_append_addr (struct dundi_ie_data *ied, unsigned char ie, struct sockaddr_in *sin)
int dundi_ie_append_answer (struct dundi_ie_data *ied, unsigned char ie, dundi_eid *eid, unsigned char protocol, unsigned short flags, unsigned short weight, char *data)
int dundi_ie_append_byte (struct dundi_ie_data *ied, unsigned char ie, unsigned char dat)
int dundi_ie_append_cause (struct dundi_ie_data *ied, unsigned char ie, unsigned char cause, char *data)
int dundi_ie_append_eid (struct dundi_ie_data *ied, unsigned char ie, dundi_eid *eid)
int dundi_ie_append_encdata (struct dundi_ie_data *ied, unsigned char ie, unsigned char *iv, void *data, int datalen)
int dundi_ie_append_hint (struct dundi_ie_data *ied, unsigned char ie, unsigned short flags, char *data)
int dundi_ie_append_int (struct dundi_ie_data *ied, unsigned char ie, unsigned int value)
int dundi_ie_append_raw (struct dundi_ie_data *ied, unsigned char ie, void *data, int datalen)
int dundi_ie_append_short (struct dundi_ie_data *ied, unsigned char ie, unsigned short value)
int dundi_ie_append_str (struct dundi_ie_data *ied, unsigned char ie, char *str)
int dundi_parse_ies (struct dundi_ies *ies, unsigned char *data, int datalen)
void dundi_set_error (void(*func)(const char *))
void dundi_set_output (void(*func)(const char *))
void dundi_showframe (struct dundi_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
int dundi_str_short_to_eid (dundi_eid *eid, const char *s)
static void internalerror (const char *str)
static void internaloutput (const char *str)
static char * proto2str (int proto, char *buf, int bufsiz)

Variables

static void(* errorf )(const char *str) = internalerror
static struct dundi_ie infoelts []
static void(* outputf )(const char *str) = internaloutput


Detailed Description

Distributed Universal Number Discovery (DUNDi).

Definition in file dundi-parser.c.


Function Documentation

static void dump_answer ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 281 of file dundi-parser.c.

References ast_eid_to_str(), dundi_answer::data, dundi_flags2str(), dundi_answer::eid, dundi_answer::flags, proto2str(), dundi_answer::protocol, and dundi_answer::weight.

00282 {
00283    struct dundi_answer *answer;
00284    char proto[40];
00285    char flags[40];
00286    char eid_str[40];
00287    char tmp[512]="";
00288    int datalen;
00289 
00290    if (len < sizeof(*answer)) {
00291       snprintf(output, maxlen, "Invalid Answer");
00292       return;
00293    }
00294 
00295    answer = (struct dundi_answer *)(value);
00296 
00297    datalen = len - offsetof(struct dundi_answer, data);
00298    if (datalen > sizeof(tmp) - 1)
00299       datalen = sizeof(tmp) - 1;
00300 
00301    memcpy(tmp, answer->data, datalen);
00302    tmp[datalen] = '\0';
00303 
00304    ast_eid_to_str(eid_str, sizeof(eid_str), &answer->eid);
00305    snprintf(output, maxlen, "[%s] %d <%s/%s> from [%s]", 
00306       dundi_flags2str(flags, sizeof(flags), ntohs(answer->flags)), 
00307       ntohs(answer->weight),
00308       proto2str(answer->protocol, proto, sizeof(proto)), 
00309          tmp, eid_str);
00310 }

static void dump_byte ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 213 of file dundi-parser.c.

References ast_copy_string().

00214 {
00215    if (len == (int)sizeof(unsigned char))
00216       snprintf(output, maxlen, "%d", *((unsigned char *)value));
00217    else
00218       ast_copy_string(output, "Invalid BYTE", maxlen);
00219 }

static void dump_cause ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 156 of file dundi-parser.c.

References ARRAY_LEN, ast_strlen_zero(), dundi_cause::causecode, causes, dundi_cause::desc, and desc.

00157 {
00158    static char *causes[] = {
00159       "SUCCESS",
00160       "GENERAL",
00161       "DYNAMIC",
00162       "NOAUTH" ,
00163       };
00164    char tmp2[256];
00165    struct dundi_cause *cause;
00166    int datalen;
00167    int causecode;
00168 
00169    if (len < sizeof(*cause)) {
00170       snprintf(output, maxlen, "<invalid contents>");
00171       return;
00172    }
00173 
00174    cause = (struct dundi_cause*) value;
00175    causecode = cause->causecode;
00176 
00177    datalen = len - offsetof(struct dundi_cause, desc);
00178    if (datalen > sizeof(tmp2) - 1)
00179       datalen = sizeof(tmp2) - 1;
00180 
00181    memcpy(tmp2, cause->desc, datalen);
00182    tmp2[datalen] = '\0';
00183 
00184    if (causecode < ARRAY_LEN(causes)) {
00185       if (ast_strlen_zero(tmp2))
00186          snprintf(output, maxlen, "%s", causes[causecode]);
00187       else
00188          snprintf(output, maxlen, "%s: %s", causes[causecode], tmp2);
00189    } else {
00190       if (ast_strlen_zero(tmp2))
00191          snprintf(output, maxlen, "%d", causecode);
00192       else
00193          snprintf(output, maxlen, "%d: %s", causecode, tmp2);
00194    }
00195 }

static void dump_cbypass ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 95 of file dundi-parser.c.

00096 {
00097    snprintf(output, maxlen, "Bypass Caches");
00098 }

static void dump_eid ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 100 of file dundi-parser.c.

References ast_eid_to_str().

00101 {
00102    if (len == 6)
00103       ast_eid_to_str(output, maxlen, (dundi_eid *)value);
00104    else
00105       snprintf(output, maxlen, "Invalid EID len %d", len);
00106 }

static void dump_encrypted ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 312 of file dundi-parser.c.

00313 {
00314    char iv[33];
00315    int x;
00316    if ((len > 16) && !(len % 16)) {
00317       /* Build up IV */
00318       for (x=0;x<16;x++) {
00319          snprintf(iv + (x << 1), 3, "%02x", ((unsigned char *)value)[x]);
00320       }
00321       snprintf(output, maxlen, "[IV %s] %d encrypted blocks\n", iv, len / 16);
00322    } else
00323       snprintf(output, maxlen, "Invalid Encrypted Datalen %d", len);
00324 }

static void dump_hint ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 128 of file dundi-parser.c.

References ast_strlen_zero(), dundi_hint::data, ast_frame::datalen, dundi_hint2str(), and dundi_hint::flags.

00129 {
00130    char tmp2[256];
00131    char tmp3[256];
00132    int datalen;
00133    struct dundi_hint *hint;
00134    if (len < sizeof(*hint)) {
00135       snprintf(output, maxlen, "<invalid contents>");
00136       return;
00137    }
00138 
00139    hint = (struct dundi_hint *) value;;
00140 
00141    datalen = len - offsetof(struct dundi_hint, data);
00142    if (datalen > sizeof(tmp3) - 1)
00143       datalen = sizeof(tmp3) - 1;
00144 
00145    memcpy(tmp3, hint->data, datalen);
00146    tmp3[datalen] = '\0';
00147 
00148    dundi_hint2str(tmp2, sizeof(tmp2), ntohs(hint->flags));
00149 
00150    if (ast_strlen_zero(tmp3))
00151       snprintf(output, maxlen, "[%s]", tmp2);
00152    else
00153       snprintf(output, maxlen, "[%s] %s", tmp2, tmp3);
00154 }

static void dump_ies ( unsigned char *  iedata,
int  spaces,
int  len 
) [static]

Definition at line 380 of file dundi-parser.c.

References ARRAY_LEN, iax2_ie::dump, DUNDI_IE_ENCDATA, infoelts, name, and outputf.

00381 {
00382    int ielen;
00383    int ie;
00384    int x;
00385    int found;
00386    char interp[1024];
00387    char tmp[1024];
00388    if (len < 2)
00389       return;
00390    while(len >= 2) {
00391       ie = iedata[0];
00392       ielen = iedata[1];
00393       /* Encrypted data is the remainder */
00394       if (ie == DUNDI_IE_ENCDATA)
00395          ielen = len - 2;
00396       if (ielen + 2> len) {
00397          snprintf(tmp, (int)sizeof(tmp), "Total IE length of %d bytes exceeds remaining frame length of %d bytes\n", ielen + 2, len);
00398          outputf(tmp);
00399          return;
00400       }
00401       found = 0;
00402       for (x = 0; x < ARRAY_LEN(infoelts); x++) {
00403          if (infoelts[x].ie == ie) {
00404             if (infoelts[x].dump) {
00405                infoelts[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen);
00406                snprintf(tmp, (int)sizeof(tmp), "   %s%-15.15s : %s\n", (spaces ? "     " : "" ), infoelts[x].name, interp);
00407                outputf(tmp);
00408             } else {
00409                if (ielen)
00410                   snprintf(interp, (int)sizeof(interp), "%d bytes", ielen);
00411                else
00412                   strcpy(interp, "Present");
00413                snprintf(tmp, (int)sizeof(tmp), "   %s%-15.15s : %s\n", (spaces ? "     " : "" ), infoelts[x].name, interp);
00414                outputf(tmp);
00415             }
00416             found++;
00417          }
00418       }
00419       if (!found) {
00420          snprintf(tmp, (int)sizeof(tmp), "   %sUnknown IE %03d  : Present\n", (spaces ? "     " : "" ), ie);
00421          outputf(tmp);
00422       }
00423       iedata += (2 + ielen);
00424       len -= (2 + ielen);
00425    }
00426    outputf("\n");
00427 }

static void dump_int ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 197 of file dundi-parser.c.

References ast_copy_string().

00198 {
00199    if (len == (int)sizeof(unsigned int))
00200       snprintf(output, maxlen, "%lu", (unsigned long)ntohl(*((unsigned int *)value)));
00201    else
00202       ast_copy_string(output, "Invalid INT", maxlen);
00203 }

static void dump_raw ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 326 of file dundi-parser.c.

00327 {
00328    int x;
00329    unsigned char *u = value;
00330    output[maxlen - 1] = '\0';
00331    strcpy(output, "[ ");
00332    for (x=0;x<len;x++) {
00333       snprintf(output + strlen(output), maxlen - strlen(output) - 1, "%02x ", u[x]);
00334    }
00335    strncat(output + strlen(output), "]", maxlen - strlen(output) - 1);
00336 }

static void dump_short ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 205 of file dundi-parser.c.

References ast_copy_string().

00206 {
00207    if (len == (int)sizeof(unsigned short))
00208       snprintf(output, maxlen, "%d", ntohs(*((unsigned short *)value)));
00209    else
00210       ast_copy_string(output, "Invalid SHORT", maxlen);
00211 }

static void dump_string ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 87 of file dundi-parser.c.

00088 {
00089    if (maxlen > len + 1)
00090       maxlen = len + 1;
00091 
00092    snprintf(output, maxlen, "%s", (char *) value);
00093 }

char* dundi_eid_to_str_short ( char *  s,
int  maxlen,
dundi_eid eid 
)

Definition at line 51 of file dundi-parser.c.

References ast_eid::eid.

Referenced by cache_lookup(), cache_save(), cache_save_hint(), and handle_command_response().

00052 {
00053    int x;
00054    char *os = s;
00055    if (maxlen < 13) {
00056       if (s && (maxlen > 0))
00057          *s = '\0';
00058    } else {
00059       for (x=0;x<6;x++) {
00060          sprintf(s, "%02X", eid->eid[x]);
00061          s += 2;
00062       }
00063    }
00064    return os;
00065 }

int dundi_eid_zero ( dundi_eid eid  ) 

Definition at line 79 of file dundi-parser.c.

References ARRAY_LEN, and ast_eid::eid.

Referenced by build_transactions(), dundi_discover(), dundi_query(), dundi_show_requests(), and precache_trans().

00080 {
00081    int x;
00082    for (x = 0; x < ARRAY_LEN(eid->eid); x++)
00083       if (eid->eid[x]) return 0;
00084    return 1;
00085 }

char* dundi_flags2str ( char *  buf,
int  bufsiz,
int  flags 
)

Definition at line 243 of file dundi-parser.c.

References ast_strlen_zero(), DUNDI_FLAG_CANMATCH, DUNDI_FLAG_COMMERCIAL, DUNDI_FLAG_EXISTS, DUNDI_FLAG_IGNOREPAT, DUNDI_FLAG_MATCHMORE, DUNDI_FLAG_MOBILE, DUNDI_FLAG_NOCOMUNSOLICIT, DUNDI_FLAG_NOUNSOLICITED, and DUNDI_FLAG_RESIDENTIAL.

Referenced by cache_lookup_internal(), dump_answer(), dundi_do_lookup(), and dundi_show_mappings().

00244 {
00245    strcpy(buf, "");
00246    buf[bufsiz-1] = '\0';
00247    if (flags & DUNDI_FLAG_EXISTS) {
00248       strncat(buf, "EXISTS|", bufsiz - strlen(buf) - 1);
00249    }
00250    if (flags & DUNDI_FLAG_MATCHMORE) {
00251       strncat(buf, "MATCHMORE|", bufsiz - strlen(buf) - 1);
00252    }
00253    if (flags & DUNDI_FLAG_CANMATCH) {
00254       strncat(buf, "CANMATCH|", bufsiz - strlen(buf) - 1);
00255    }
00256    if (flags & DUNDI_FLAG_IGNOREPAT) {
00257       strncat(buf, "IGNOREPAT|", bufsiz - strlen(buf) - 1);
00258    }
00259    if (flags & DUNDI_FLAG_RESIDENTIAL) {
00260       strncat(buf, "RESIDENCE|", bufsiz - strlen(buf) - 1);
00261    }
00262    if (flags & DUNDI_FLAG_COMMERCIAL) {
00263       strncat(buf, "COMMERCIAL|", bufsiz - strlen(buf) - 1);
00264    }
00265    if (flags & DUNDI_FLAG_MOBILE) {
00266       strncat(buf, "MOBILE", bufsiz - strlen(buf) - 1);
00267    }
00268    if (flags & DUNDI_FLAG_NOUNSOLICITED) {
00269       strncat(buf, "NOUNSLCTD|", bufsiz - strlen(buf) - 1);
00270    }
00271    if (flags & DUNDI_FLAG_NOCOMUNSOLICIT) {
00272       strncat(buf, "NOCOMUNSLTD|", bufsiz - strlen(buf) - 1);
00273    }
00274    /* Get rid of trailing | */
00275    if (ast_strlen_zero(buf))
00276       strcpy(buf, "NONE|");
00277    buf[strlen(buf)-1] = '\0';
00278    return buf;
00279 }

char* dundi_hint2str ( char *  buf,
int  bufsiz,
int  flags 
)

Definition at line 108 of file dundi-parser.c.

References ast_strlen_zero(), DUNDI_HINT_DONT_ASK, DUNDI_HINT_TTL_EXPIRED, and DUNDI_HINT_UNAFFECTED.

Referenced by dump_hint().

00109 {
00110    strcpy(buf, "");
00111    buf[bufsiz-1] = '\0';
00112    if (flags & DUNDI_HINT_TTL_EXPIRED) {
00113       strncat(buf, "TTLEXPIRED|", bufsiz - strlen(buf) - 1);
00114    }
00115    if (flags & DUNDI_HINT_DONT_ASK) {
00116       strncat(buf, "DONTASK|", bufsiz - strlen(buf) - 1);
00117    }
00118    if (flags & DUNDI_HINT_UNAFFECTED) {
00119       strncat(buf, "UNAFFECTED|", bufsiz - strlen(buf) - 1);
00120    }
00121    /* Get rid of trailing | */
00122    if (ast_strlen_zero(buf))
00123       strcpy(buf, "NONE|");
00124    buf[strlen(buf)-1] = '\0';
00125    return buf;
00126 }

const char* dundi_ie2str ( int  ie  ) 

Definition at line 370 of file dundi-parser.c.

References ARRAY_LEN, infoelts, and iax2_ie::name.

Referenced by dundi_ie_append_answer(), dundi_ie_append_cause(), dundi_ie_append_encdata(), dundi_ie_append_hint(), dundi_ie_append_raw(), and dundi_parse_ies().

00371 {
00372    int x;
00373    for (x = 0; x < ARRAY_LEN(infoelts); x++) {
00374       if (infoelts[x].ie == ie)
00375          return infoelts[x].name;
00376    }
00377    return "Unknown IE";
00378 }

int dundi_ie_append ( struct dundi_ie_data ied,
unsigned char  ie 
)

Definition at line 620 of file dundi-parser.c.

References dundi_ie_append_raw().

Referenced by dundi_discover().

00621 {
00622    return dundi_ie_append_raw(ied, ie, NULL, 0);
00623 }

int dundi_ie_append_addr ( struct dundi_ie_data ied,
unsigned char  ie,
struct sockaddr_in *  sin 
)

Definition at line 586 of file dundi-parser.c.

References dundi_ie_append_raw().

00587 {
00588    return dundi_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in));
00589 }

int dundi_ie_append_answer ( struct dundi_ie_data ied,
unsigned char  ie,
dundi_eid eid,
unsigned char  protocol,
unsigned short  flags,
unsigned short  weight,
char *  data 
)

Definition at line 559 of file dundi-parser.c.

References dundi_ie_data::buf, dundi_ie2str(), ast_eid::eid, errorf, and dundi_ie_data::pos.

Referenced by dundi_lookup_thread(), and precache_trans().

00560 {
00561    char tmp[256];
00562    int datalen = data ? strlen(data) + 11 : 11;
00563    int x;
00564    unsigned short myw;
00565    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00566       snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", dundi_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
00567       errorf(tmp);
00568       return -1;
00569    }
00570    ied->buf[ied->pos++] = ie;
00571    ied->buf[ied->pos++] = datalen;
00572    for (x=0;x<6;x++)
00573       ied->buf[ied->pos++] = eid->eid[x];
00574    ied->buf[ied->pos++] = protocol;
00575    myw = htons(flags);
00576    memcpy(ied->buf + ied->pos, &myw, 2);
00577    ied->pos += 2;
00578    myw = htons(weight);
00579    memcpy(ied->buf + ied->pos, &myw, 2);
00580    ied->pos += 2;
00581    memcpy(ied->buf + ied->pos, data, datalen-11);
00582    ied->pos += datalen-11;
00583    return 0;
00584 }

int dundi_ie_append_byte ( struct dundi_ie_data ied,
unsigned char  ie,
unsigned char  dat 
)

Definition at line 615 of file dundi-parser.c.

References dundi_ie_append_raw().

Referenced by handle_command_response().

00616 {
00617    return dundi_ie_append_raw(ied, ie, &dat, 1);
00618 }

int dundi_ie_append_cause ( struct dundi_ie_data ied,
unsigned char  ie,
unsigned char  cause,
char *  data 
)

Definition at line 503 of file dundi-parser.c.

References dundi_ie_data::buf, dundi_ie2str(), errorf, and dundi_ie_data::pos.

Referenced by dundi_answer_entity(), dundi_answer_query(), dundi_lookup_thread(), dundi_prop_precache(), and handle_command_response().

00504 {
00505    char tmp[256];
00506    int datalen = data ? strlen(data) + 1 : 1;
00507    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00508       snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", dundi_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
00509       errorf(tmp);
00510       return -1;
00511    }
00512    ied->buf[ied->pos++] = ie;
00513    ied->buf[ied->pos++] = datalen;
00514    ied->buf[ied->pos++] = cause;
00515    memcpy(ied->buf + ied->pos, data, datalen-1);
00516    ied->pos += datalen-1;
00517    return 0;
00518 }

int dundi_ie_append_eid ( struct dundi_ie_data ied,
unsigned char  ie,
dundi_eid eid 
)

Definition at line 610 of file dundi-parser.c.

References dundi_ie_append_raw().

Referenced by do_register(), dundi_discover(), dundi_encrypt(), dundi_ie_append_eid_appropriately(), dundi_query(), handle_command_response(), and precache_trans().

00611 {
00612    return dundi_ie_append_raw(ied, ie, (unsigned char *)eid, sizeof(dundi_eid));
00613 }

int dundi_ie_append_encdata ( struct dundi_ie_data ied,
unsigned char  ie,
unsigned char *  iv,
void *  data,
int  datalen 
)

Definition at line 539 of file dundi-parser.c.

References dundi_ie_data::buf, dundi_ie2str(), errorf, and dundi_ie_data::pos.

Referenced by dundi_encrypt(), and handle_command_response().

00540 {
00541    char tmp[256];
00542    datalen += 16;
00543    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00544       snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", dundi_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
00545       errorf(tmp);
00546       return -1;
00547    }
00548    ied->buf[ied->pos++] = ie;
00549    ied->buf[ied->pos++] = datalen;
00550    memcpy(ied->buf + ied->pos, iv, 16);
00551    ied->pos += 16;
00552    if (data) {
00553       memcpy(ied->buf + ied->pos, data, datalen-16);
00554       ied->pos += datalen-16;
00555    }
00556    return 0;
00557 }

int dundi_ie_append_hint ( struct dundi_ie_data ied,
unsigned char  ie,
unsigned short  flags,
char *  data 
)

Definition at line 520 of file dundi-parser.c.

References dundi_ie_data::buf, dundi_ie2str(), errorf, and dundi_ie_data::pos.

Referenced by dundi_lookup_thread(), dundi_query_thread(), and precache_trans().

00521 {
00522    char tmp[256];
00523    int datalen = data ? strlen(data) + 2 : 2;
00524    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00525       snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", dundi_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
00526       errorf(tmp);
00527       return -1;
00528    }
00529    ied->buf[ied->pos++] = ie;
00530    ied->buf[ied->pos++] = datalen;
00531    flags = htons(flags);
00532    memcpy(ied->buf + ied->pos, &flags, sizeof(flags));
00533    ied->pos += 2;
00534    memcpy(ied->buf + ied->pos, data, datalen-1);
00535    ied->pos += datalen-2;
00536    return 0;
00537 }

int dundi_ie_append_int ( struct dundi_ie_data ied,
unsigned char  ie,
unsigned int  value 
)

Definition at line 591 of file dundi-parser.c.

References dundi_ie_append_raw().

Referenced by dundi_encrypt().

00592 {
00593    unsigned int newval;
00594    newval = htonl(value);
00595    return dundi_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00596 }

int dundi_ie_append_raw ( struct dundi_ie_data ied,
unsigned char  ie,
void *  data,
int  datalen 
)

Definition at line 488 of file dundi-parser.c.

References dundi_ie_data::buf, dundi_ie2str(), errorf, and dundi_ie_data::pos.

Referenced by dundi_encrypt(), dundi_ie_append(), dundi_ie_append_addr(), dundi_ie_append_byte(), dundi_ie_append_eid(), dundi_ie_append_int(), dundi_ie_append_short(), dundi_ie_append_str(), and handle_command_response().

00489 {
00490    char tmp[256];
00491    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00492       snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", dundi_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
00493       errorf(tmp);
00494       return -1;
00495    }
00496    ied->buf[ied->pos++] = ie;
00497    ied->buf[ied->pos++] = datalen;
00498    memcpy(ied->buf + ied->pos, data, datalen);
00499    ied->pos += datalen;
00500    return 0;
00501 }

int dundi_ie_append_short ( struct dundi_ie_data ied,
unsigned char  ie,
unsigned short  value 
)

Definition at line 598 of file dundi-parser.c.

References dundi_ie_append_raw().

Referenced by do_register(), dundi_discover(), dundi_lookup_thread(), dundi_query(), handle_command_response(), and precache_trans().

00599 {
00600    unsigned short newval;
00601    newval = htons(value);
00602    return dundi_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00603 }

int dundi_ie_append_str ( struct dundi_ie_data ied,
unsigned char  ie,
char *  str 
)

Definition at line 605 of file dundi-parser.c.

References dundi_ie_append_raw().

Referenced by dundi_discover(), dundi_query(), dundi_query_thread(), and precache_trans().

00606 {
00607    return dundi_ie_append_raw(ied, ie, str, strlen(str));
00608 }

int dundi_parse_ies ( struct dundi_ies ies,
unsigned char *  data,
int  datalen 
)

Definition at line 635 of file dundi-parser.c.

References dundi_ies::anscount, dundi_ies::answers, dundi_ies::called_context, dundi_ies::called_number, dundi_ies::cause, dundi_ies::causestr, dundi_ies::cbypass, dundi_ie2str(), DUNDI_IE_ANSWER, DUNDI_IE_CACHEBYPASS, DUNDI_IE_CALLED_CONTEXT, DUNDI_IE_CALLED_NUMBER, DUNDI_IE_CAUSE, DUNDI_IE_COUNTRY, DUNDI_IE_DEPARTMENT, DUNDI_IE_EID, DUNDI_IE_EID_DIRECT, DUNDI_IE_EMAIL, DUNDI_IE_ENCDATA, DUNDI_IE_EXPIRATION, DUNDI_IE_HINT, DUNDI_IE_IPADDR, DUNDI_IE_KEYCRC32, DUNDI_IE_LOCALITY, DUNDI_IE_ORGANIZATION, DUNDI_IE_PHONE, DUNDI_IE_REQEID, DUNDI_IE_SHAREDKEY, DUNDI_IE_SIGNATURE, DUNDI_IE_STATE_PROV, DUNDI_IE_TTL, DUNDI_IE_UNKNOWN, DUNDI_IE_VERSION, DUNDI_MAX_ANSWERS, DUNDI_MAX_STACK, dundi_ies::eid_direct, dundi_ies::eidcount, dundi_ies::eids, dundi_ies::encblock, dundi_ies::enclen, dundi_ies::encsharedkey, dundi_ies::encsig, errorf, dundi_ies::expiration, dundi_ies::hint, dundi_ies::keycrc32, len(), outputf, dundi_ies::q_country, dundi_ies::q_dept, dundi_ies::q_email, dundi_ies::q_ipaddr, dundi_ies::q_locality, dundi_ies::q_org, dundi_ies::q_phone, dundi_ies::q_stateprov, dundi_ies::reqeid, dundi_ies::ttl, dundi_ies::unknowncmd, and dundi_ies::version.

Referenced by handle_command_response().

00636 {
00637    /* Parse data into information elements */
00638    int len;
00639    int ie;
00640    char tmp[256];
00641    memset(ies, 0, (int)sizeof(struct dundi_ies));
00642    ies->ttl = -1;
00643    ies->expiration = -1;
00644    ies->unknowncmd = -1;
00645    ies->cause = -1;
00646    while(datalen >= 2) {
00647       ie = data[0];
00648       len = data[1];
00649       if (len > datalen - 2) {
00650          errorf("Information element length exceeds message size\n");
00651          return -1;
00652       }
00653       switch(ie) {
00654       case DUNDI_IE_EID:
00655       case DUNDI_IE_EID_DIRECT:
00656          if (len != (int)sizeof(dundi_eid)) {
00657             errorf("Improper entity identifer, expecting 6 bytes!\n");
00658          } else if (ies->eidcount < DUNDI_MAX_STACK) {
00659             ies->eids[ies->eidcount] = (dundi_eid *)(data + 2);
00660             ies->eid_direct[ies->eidcount] = (ie == DUNDI_IE_EID_DIRECT);
00661             ies->eidcount++;
00662          } else
00663             errorf("Too many entities in stack!\n");
00664          break;
00665       case DUNDI_IE_REQEID:
00666          if (len != (int)sizeof(dundi_eid)) {
00667             errorf("Improper requested entity identifer, expecting 6 bytes!\n");
00668          } else
00669             ies->reqeid = (dundi_eid *)(data + 2);
00670          break;
00671       case DUNDI_IE_CALLED_CONTEXT:
00672          ies->called_context = (char *)data + 2;
00673          break;
00674       case DUNDI_IE_CALLED_NUMBER:
00675          ies->called_number = (char *)data + 2;
00676          break;
00677       case DUNDI_IE_ANSWER:
00678          if (len < sizeof(struct dundi_answer)) {
00679             snprintf(tmp, (int)sizeof(tmp), "Answer expected to be >=%d bytes long but was %d\n", (int)sizeof(struct dundi_answer), len);
00680             errorf(tmp);
00681          } else {
00682             if (ies->anscount < DUNDI_MAX_ANSWERS)
00683                ies->answers[ies->anscount++]= (struct dundi_answer *)(data + 2);
00684             else 
00685                errorf("Ignoring extra answers!\n");
00686          }
00687          break;
00688       case DUNDI_IE_TTL:
00689          if (len != (int)sizeof(unsigned short)) {
00690             snprintf(tmp, (int)sizeof(tmp), "Expecting ttl to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00691             errorf(tmp);
00692          } else
00693             ies->ttl = ntohs(*((unsigned short *)(data + 2)));
00694          break;
00695       case DUNDI_IE_VERSION:
00696          if (len != (int)sizeof(unsigned short)) {
00697             snprintf(tmp, (int)sizeof(tmp),  "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00698             errorf(tmp);
00699          } else
00700             ies->version = ntohs(*((unsigned short *)(data + 2)));
00701          break;
00702       case DUNDI_IE_EXPIRATION:
00703          if (len != (int)sizeof(unsigned short)) {
00704             snprintf(tmp, (int)sizeof(tmp),  "Expecting expiration to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00705             errorf(tmp);
00706          } else
00707             ies->expiration = ntohs(*((unsigned short *)(data + 2)));
00708          break;
00709       case DUNDI_IE_KEYCRC32:
00710          if (len != (int)sizeof(unsigned int)) {
00711             snprintf(tmp, (int)sizeof(tmp),  "Expecting expiration to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00712             errorf(tmp);
00713          } else
00714             ies->keycrc32 = ntohl(*((unsigned int *)(data + 2)));
00715          break;
00716       case DUNDI_IE_UNKNOWN:
00717          if (len == 1)
00718             ies->unknowncmd = data[2];
00719          else {
00720             snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len);
00721             errorf(tmp);
00722          }
00723          break;
00724       case DUNDI_IE_CAUSE:
00725          if (len >= 1) {
00726             ies->cause = data[2];
00727             ies->causestr = (char *)data + 3;
00728          } else {
00729             snprintf(tmp, (int)sizeof(tmp), "Expected at least one byte cause, but was %d long\n", len);
00730             errorf(tmp);
00731          }
00732          break;
00733       case DUNDI_IE_HINT:
00734          if (len >= 2) {
00735             ies->hint = (struct dundi_hint *)(data + 2);
00736          } else {
00737             snprintf(tmp, (int)sizeof(tmp), "Expected at least two byte hint, but was %d long\n", len);
00738             errorf(tmp);
00739          }
00740          break;
00741       case DUNDI_IE_DEPARTMENT:
00742          ies->q_dept = (char *)data + 2;
00743          break;
00744       case DUNDI_IE_ORGANIZATION:
00745          ies->q_org = (char *)data + 2;
00746          break;
00747       case DUNDI_IE_LOCALITY:
00748          ies->q_locality = (char *)data + 2;
00749          break;
00750       case DUNDI_IE_STATE_PROV:
00751          ies->q_stateprov = (char *)data + 2;
00752          break;
00753       case DUNDI_IE_COUNTRY:
00754          ies->q_country = (char *)data + 2;
00755          break;
00756       case DUNDI_IE_EMAIL:
00757          ies->q_email = (char *)data + 2;
00758          break;
00759       case DUNDI_IE_PHONE:
00760          ies->q_phone = (char *)data + 2;
00761          break;
00762       case DUNDI_IE_IPADDR:
00763          ies->q_ipaddr = (char *)data + 2;
00764          break;
00765       case DUNDI_IE_ENCDATA:
00766          /* Recalculate len as the remainder of the message, regardless of
00767             theoretical length */
00768          len = datalen - 2;
00769          if ((len > 16) && !(len % 16)) {
00770             ies->encblock = (struct dundi_encblock *)(data + 2);
00771             ies->enclen = len - 16;
00772          } else {
00773             snprintf(tmp, (int)sizeof(tmp), "Invalid encrypted data length %d\n", len);
00774             errorf(tmp);
00775          }
00776          break;
00777       case DUNDI_IE_SHAREDKEY:
00778          if (len == 128) {
00779             ies->encsharedkey = (unsigned char *)(data + 2);
00780          } else {
00781             snprintf(tmp, (int)sizeof(tmp), "Invalid encrypted shared key length %d\n", len);
00782             errorf(tmp);
00783          }
00784          break;
00785       case DUNDI_IE_SIGNATURE:
00786          if (len == 128) {
00787             ies->encsig = (unsigned char *)(data + 2);
00788          } else {
00789             snprintf(tmp, (int)sizeof(tmp), "Invalid encrypted signature length %d\n", len);
00790             errorf(tmp);
00791          }
00792          break;
00793       case DUNDI_IE_CACHEBYPASS:
00794          ies->cbypass = 1;
00795          break;
00796       default:
00797          snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", dundi_ie2str(ie), ie, len);
00798          outputf(tmp);
00799       }
00800       /* Overwrite information element with 0, to null terminate previous portion */
00801       data[0] = 0;
00802       datalen -= (len + 2);
00803       data += (len + 2);
00804    }
00805    /* Null-terminate last field */
00806    *data = '\0';
00807    if (datalen) {
00808       errorf("Invalid information element contents, strange boundary\n");
00809       return -1;
00810    }
00811    return 0;
00812 }

void dundi_set_error ( void(*)(const char *)  func  ) 

Definition at line 630 of file dundi-parser.c.

References errorf.

Referenced by load_module().

00631 {
00632    errorf = func;
00633 }

void dundi_set_output ( void(*)(const char *)  func  ) 

Definition at line 625 of file dundi-parser.c.

References outputf.

Referenced by load_module().

00626 {
00627    outputf = func;
00628 }

void dundi_showframe ( struct dundi_hdr fhi,
int  rx,
struct sockaddr_in *  sin,
int  datalen 
)

Definition at line 429 of file dundi-parser.c.

References ast_inet_ntoa(), dundi_hdr::cmdflags, dundi_hdr::cmdresp, commands, dundi_hdr::dtrans, dump_ies(), DUNDI_FLAG_RESERVED, DUNDI_FLAG_RETRANS, dundi_hdr::ies, dundi_hdr::iseqno, dundi_hdr::oseqno, outputf, and dundi_hdr::strans.

Referenced by dundi_send(), dundi_xmit(), handle_command_response(), and socket_read().

00430 {
00431    char *pref[] = {
00432       "Tx",
00433       "Rx",
00434       "    ETx",
00435       "    Erx" };
00436    char *commands[] = {
00437       "ACK         ",
00438       "DPDISCOVER  ",
00439       "DPRESPONSE  ",
00440       "EIDQUERY    ",
00441       "EIDRESPONSE ",
00442       "PRECACHERQ  ",
00443       "PRECACHERP  ",
00444       "INVALID     ",
00445       "UNKNOWN CMD ",
00446       "NULL        ",
00447       "REQREQ      ",
00448       "REGRESPONSE ",
00449       "CANCEL      ",
00450       "ENCRYPT     ",
00451       "ENCREJ      " };
00452    char class2[20];
00453    char *class;
00454    char subclass2[20];
00455    char *subclass;
00456    char tmp[256];
00457    char retries[20];
00458    if (ntohs(fhi->dtrans) & DUNDI_FLAG_RETRANS)
00459       strcpy(retries, "Yes");
00460    else
00461       strcpy(retries, "No");
00462    if ((ntohs(fhi->strans) & DUNDI_FLAG_RESERVED)) {
00463       /* Ignore frames with high bit set to 1 */
00464       return;
00465    }
00466    if ((fhi->cmdresp & 0x3f) > (int)sizeof(commands)/(int)sizeof(char *)) {
00467       snprintf(class2, (int)sizeof(class2), "(%d?)", fhi->cmdresp);
00468       class = class2;
00469    } else {
00470       class = commands[(int)(fhi->cmdresp & 0x3f)];
00471    }
00472    snprintf(subclass2, (int)sizeof(subclass2), "%02x", fhi->cmdflags);
00473    subclass = subclass2;
00474    snprintf(tmp, (int)sizeof(tmp), 
00475       "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s (%s)\n",
00476       pref[rx],
00477       retries, fhi->oseqno, fhi->iseqno, class, fhi->cmdresp & 0x40 ? "Response" : "Command");
00478    outputf(tmp);
00479    snprintf(tmp, (int)sizeof(tmp), 
00480       "%s     Flags: %s STrans: %5.5d  DTrans: %5.5d [%s:%d]%s\n", (rx > 1) ? "     " : "",
00481       subclass, ntohs(fhi->strans) & ~DUNDI_FLAG_RESERVED, ntohs(fhi->dtrans) & ~DUNDI_FLAG_RETRANS,
00482       ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port),
00483       fhi->cmdresp & 0x80 ? " (Final)" : "");
00484    outputf(tmp);
00485    dump_ies(fhi->ies, rx > 1, datalen);
00486 }

int dundi_str_short_to_eid ( dundi_eid eid,
const char *  s 
)

Definition at line 67 of file dundi-parser.c.

References ast_eid::eid.

Referenced by cache_lookup_internal().

00068 {
00069    unsigned int eid_int[6];
00070    int x;
00071    if (sscanf(s, "%2x%2x%2x%2x%2x%2x", &eid_int[0], &eid_int[1], &eid_int[2],
00072        &eid_int[3], &eid_int[4], &eid_int[5]) != 6)
00073          return -1;
00074    for (x = 0; x < 6; x++)
00075       eid->eid[x] = eid_int[x];
00076    return 0;
00077 }

static void internalerror ( const char *  str  )  [static]

Definition at line 43 of file dundi-parser.c.

00044 {
00045    fprintf(stderr, "WARNING: %s", str);
00046 }

static void internaloutput ( const char *  str  )  [static]

Definition at line 38 of file dundi-parser.c.

00039 {
00040    fputs(str, stdout);
00041 }

static char* proto2str ( int  proto,
char *  buf,
int  bufsiz 
) [static]

Definition at line 221 of file dundi-parser.c.

References DUNDI_PROTO_H323, DUNDI_PROTO_IAX, DUNDI_PROTO_NONE, and DUNDI_PROTO_SIP.

Referenced by dump_answer().

00222 {  
00223    switch(proto) {
00224    case DUNDI_PROTO_NONE:
00225       strncpy(buf, "None", bufsiz - 1);
00226       break;
00227    case DUNDI_PROTO_IAX:
00228       strncpy(buf, "IAX", bufsiz - 1);
00229       break;
00230    case DUNDI_PROTO_SIP:
00231       strncpy(buf, "SIP", bufsiz - 1);
00232       break;
00233    case DUNDI_PROTO_H323:
00234       strncpy(buf, "H.323", bufsiz - 1);
00235       break;
00236    default:
00237       snprintf(buf, bufsiz, "Unknown Proto(%d)", proto);
00238    }
00239    buf[bufsiz-1] = '\0';
00240    return buf;
00241 }


Variable Documentation

void(* errorf)(const char *str) = internalerror [static]

struct dundi_ie infoelts[] [static]

void(* outputf)(const char *str) = internaloutput [static]


Generated on Wed Oct 28 11:52:20 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6