Thu Jul 9 13:41:17 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"

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)
int dundi_eid_cmp (dundi_eid *eid1, dundi_eid *eid2)
char * dundi_eid_to_str (char *s, int maxlen, dundi_eid *eid)
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)
int dundi_str_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 ies []
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 315 of file dundi-parser.c.

References dundi_answer::data, dundi_eid_to_str(), dundi_flags2str(), dundi_answer::flags, and proto2str().

00316 {
00317    struct dundi_answer *answer;
00318    char proto[40];
00319    char flags[40];
00320    char eid_str[40];
00321    char tmp[512]="";
00322    int datalen;
00323 
00324    if (len < sizeof(*answer)) {
00325       snprintf(output, maxlen, "Invalid Answer");
00326       return;
00327    }
00328 
00329    answer = (struct dundi_answer *)(value);
00330 
00331    datalen = len - offsetof(struct dundi_answer, data);
00332    if (datalen > sizeof(tmp) - 1)
00333       datalen = sizeof(tmp) - 1;
00334 
00335    memcpy(tmp, answer->data, datalen);
00336    tmp[datalen] = '\0';
00337 
00338    dundi_eid_to_str(eid_str, sizeof(eid_str), &answer->eid);
00339    snprintf(output, maxlen, "[%s] %d <%s/%s> from [%s]", 
00340       dundi_flags2str(flags, sizeof(flags), ntohs(answer->flags)), 
00341       ntohs(answer->weight),
00342       proto2str(answer->protocol, proto, sizeof(proto)), 
00343          tmp, eid_str);
00344 }

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

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

References ast_copy_string().

00248 {
00249    if (len == (int)sizeof(unsigned char))
00250       snprintf(output, maxlen, "%d", *((unsigned char *)value));
00251    else
00252       ast_copy_string(output, "Invalid BYTE", maxlen);
00253 }

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

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

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

00191 {
00192    static char *causes[] = {
00193       "SUCCESS",
00194       "GENERAL",
00195       "DYNAMIC",
00196       "NOAUTH" ,
00197       };
00198    char tmp2[256];
00199    struct dundi_cause *cause;
00200    int datalen;
00201    int causecode;
00202 
00203    if (len < sizeof(*cause)) {
00204       snprintf(output, maxlen, "<invalid contents>");
00205       return;
00206    }
00207 
00208    cause = (struct dundi_cause*) value;
00209    causecode = cause->causecode;
00210 
00211    datalen = len - offsetof(struct dundi_cause, desc);
00212    if (datalen > sizeof(tmp2) - 1)
00213       datalen = sizeof(tmp2) - 1;
00214 
00215    memcpy(tmp2, cause->desc, datalen);
00216    tmp2[datalen] = '\0';
00217 
00218    if (causecode < ARRAY_LEN(causes)) {
00219       if (ast_strlen_zero(tmp2))
00220          snprintf(output, maxlen, "%s", causes[causecode]);
00221       else
00222          snprintf(output, maxlen, "%s: %s", causes[causecode], tmp2);
00223    } else {
00224       if (ast_strlen_zero(tmp2))
00225          snprintf(output, maxlen, "%d", causecode);
00226       else
00227          snprintf(output, maxlen, "%d: %s", causecode, tmp2);
00228    }
00229 }

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

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

00130 {
00131    snprintf(output, maxlen, "Bypass Caches");
00132 }

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

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

References dundi_eid_to_str().

00135 {
00136    if (len == 6)
00137       dundi_eid_to_str(output, maxlen, (dundi_eid *)value);
00138    else
00139       snprintf(output, maxlen, "Invalid EID len %d", len);
00140 }

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

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

00347 {
00348    char iv[33];
00349    int x;
00350    if ((len > 16) && !(len % 16)) {
00351       /* Build up IV */
00352       for (x=0;x<16;x++) {
00353          snprintf(iv + (x << 1), 3, "%02x", ((unsigned char *)value)[x]);
00354       }
00355       snprintf(output, maxlen, "[IV %s] %d encrypted blocks\n", iv, len / 16);
00356    } else
00357       snprintf(output, maxlen, "Invalid Encrypted Datalen %d", len);
00358 }

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

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

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

00163 {
00164    char tmp2[256];
00165    char tmp3[256];
00166    int datalen;
00167    struct dundi_hint *hint;
00168    if (len < sizeof(*hint)) {
00169       snprintf(output, maxlen, "<invalid contents>");
00170       return;
00171    }
00172 
00173    hint = (struct dundi_hint *) value;;
00174 
00175    datalen = len - offsetof(struct dundi_hint, data);
00176    if (datalen > sizeof(tmp3) - 1)
00177       datalen = sizeof(tmp3) - 1;
00178 
00179    memcpy(tmp3, hint->data, datalen);
00180    tmp3[datalen] = '\0';
00181 
00182    dundi_hint2str(tmp2, sizeof(tmp2), ntohs(hint->flags));
00183 
00184    if (ast_strlen_zero(tmp3))
00185       snprintf(output, maxlen, "[%s]", tmp2);
00186    else
00187       snprintf(output, maxlen, "[%s] %s", tmp2, tmp3);
00188 }

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

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

References DUNDI_IE_ENCDATA, ies, name, and outputf.

00415 {
00416    int ielen;
00417    int ie;
00418    int x;
00419    int found;
00420    char interp[1024];
00421    char tmp[1024];
00422    if (len < 2)
00423       return;
00424    while(len >= 2) {
00425       ie = iedata[0];
00426       ielen = iedata[1];
00427       /* Encrypted data is the remainder */
00428       if (ie == DUNDI_IE_ENCDATA)
00429          ielen = len - 2;
00430       if (ielen + 2> len) {
00431          snprintf(tmp, (int)sizeof(tmp), "Total IE length of %d bytes exceeds remaining frame length of %d bytes\n", ielen + 2, len);
00432          outputf(tmp);
00433          return;
00434       }
00435       found = 0;
00436       for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
00437          if (ies[x].ie == ie) {
00438             if (ies[x].dump) {
00439                ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen);
00440                snprintf(tmp, (int)sizeof(tmp), "   %s%-15.15s : %s\n", (spaces ? "     " : "" ), ies[x].name, interp);
00441                outputf(tmp);
00442             } else {
00443                if (ielen)
00444                   snprintf(interp, (int)sizeof(interp), "%d bytes", ielen);
00445                else
00446                   strcpy(interp, "Present");
00447                snprintf(tmp, (int)sizeof(tmp), "   %s%-15.15s : %s\n", (spaces ? "     " : "" ), ies[x].name, interp);
00448                outputf(tmp);
00449             }
00450             found++;
00451          }
00452       }
00453       if (!found) {
00454          snprintf(tmp, (int)sizeof(tmp), "   %sUnknown IE %03d  : Present\n", (spaces ? "     " : "" ), ie);
00455          outputf(tmp);
00456       }
00457       iedata += (2 + ielen);
00458       len -= (2 + ielen);
00459    }
00460    outputf("\n");
00461 }

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

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

References ast_copy_string().

00232 {
00233    if (len == (int)sizeof(unsigned int))
00234       snprintf(output, maxlen, "%lu", (unsigned long)ntohl(*((unsigned int *)value)));
00235    else
00236       ast_copy_string(output, "Invalid INT", maxlen);
00237 }

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

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

00361 {
00362    int x;
00363    unsigned char *u = value;
00364    output[maxlen - 1] = '\0';
00365    strcpy(output, "[ ");
00366    for (x=0;x<len;x++) {
00367       snprintf(output + strlen(output), maxlen - strlen(output) - 1, "%02x ", u[x]);
00368    }
00369    strncat(output + strlen(output), "]", maxlen - strlen(output) - 1);
00370 }

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

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

References ast_copy_string().

00240 {
00241    if (len == (int)sizeof(unsigned short))
00242       snprintf(output, maxlen, "%d", ntohs(*((unsigned short *)value)));
00243    else
00244       ast_copy_string(output, "Invalid SHORT", maxlen);
00245 }

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

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

00122 {
00123    if (maxlen > len + 1)
00124       maxlen = len + 1;
00125 
00126    snprintf(output, maxlen, "%s", (char *) value);
00127 }

int dundi_eid_cmp ( dundi_eid eid1,
dundi_eid eid2 
)

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

Referenced by build_peer(), build_transactions(), destroy_trans(), dundi_answer_entity(), dundi_answer_query(), dundi_ie_append_eid_appropriately(), dundi_lookup_internal(), dundi_query_thread(), find_peer(), optimize_transactions(), and register_request().

00117 {
00118    return memcmp(eid1, eid2, sizeof(dundi_eid));
00119 }

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

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

References _dundi_eid::eid.

Referenced by append_transaction(), build_transactions(), cache_lookup(), cache_lookup_internal(), check_key(), complete_peer_helper(), destroy_trans(), do_autokill(), do_register(), do_register_expire(), dump_answer(), dump_eid(), dundi_answer_entity(), dundi_lookup_internal(), dundi_lookup_local(), dundi_lookup_thread(), dundi_precache_thread(), dundi_prop_precache(), dundi_query_thread(), dundi_send(), dundi_show_entityid(), dundi_show_peer(), dundi_show_peers(), dundi_show_requests(), handle_command_response(), populate_addr(), register_request(), reset_global_eid(), and update_key().

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

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

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

References _dundi_eid::eid.

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

00069 {
00070    int x;
00071    char *os = s;
00072    if (maxlen < 13) {
00073       if (s && (maxlen > 0))
00074          *s = '\0';
00075    } else {
00076       for (x=0;x<6;x++) {
00077          sprintf(s, "%02X", eid->eid[x]);
00078          s += 2;
00079       }
00080    }
00081    return os;
00082 }

int dundi_eid_zero ( dundi_eid eid  ) 

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

References ARRAY_LEN, and _dundi_eid::eid.

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

00109 {
00110    int x;
00111    for (x = 0; x < ARRAY_LEN(eid->eid); x++)
00112       if (eid->eid[x]) return 0;
00113    return 1;
00114 }

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

Definition at line 277 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().

00278 {
00279    strcpy(buf, "");
00280    buf[bufsiz-1] = '\0';
00281    if (flags & DUNDI_FLAG_EXISTS) {
00282       strncat(buf, "EXISTS|", bufsiz - strlen(buf) - 1);
00283    }
00284    if (flags & DUNDI_FLAG_MATCHMORE) {
00285       strncat(buf, "MATCHMORE|", bufsiz - strlen(buf) - 1);
00286    }
00287    if (flags & DUNDI_FLAG_CANMATCH) {
00288       strncat(buf, "CANMATCH|", bufsiz - strlen(buf) - 1);
00289    }
00290    if (flags & DUNDI_FLAG_IGNOREPAT) {
00291       strncat(buf, "IGNOREPAT|", bufsiz - strlen(buf) - 1);
00292    }
00293    if (flags & DUNDI_FLAG_RESIDENTIAL) {
00294       strncat(buf, "RESIDENCE|", bufsiz - strlen(buf) - 1);
00295    }
00296    if (flags & DUNDI_FLAG_COMMERCIAL) {
00297       strncat(buf, "COMMERCIAL|", bufsiz - strlen(buf) - 1);
00298    }
00299    if (flags & DUNDI_FLAG_MOBILE) {
00300       strncat(buf, "MOBILE", bufsiz - strlen(buf) - 1);
00301    }
00302    if (flags & DUNDI_FLAG_NOUNSOLICITED) {
00303       strncat(buf, "NOUNSLCTD|", bufsiz - strlen(buf) - 1);
00304    }
00305    if (flags & DUNDI_FLAG_NOCOMUNSOLICIT) {
00306       strncat(buf, "NOCOMUNSLTD|", bufsiz - strlen(buf) - 1);
00307    }
00308    /* Get rid of trailing | */
00309    if (ast_strlen_zero(buf))
00310       strcpy(buf, "NONE|");
00311    buf[strlen(buf)-1] = '\0';
00312    return buf;
00313 }

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

Definition at line 142 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().

00143 {
00144    strcpy(buf, "");
00145    buf[bufsiz-1] = '\0';
00146    if (flags & DUNDI_HINT_TTL_EXPIRED) {
00147       strncat(buf, "TTLEXPIRED|", bufsiz - strlen(buf) - 1);
00148    }
00149    if (flags & DUNDI_HINT_DONT_ASK) {
00150       strncat(buf, "DONTASK|", bufsiz - strlen(buf) - 1);
00151    }
00152    if (flags & DUNDI_HINT_UNAFFECTED) {
00153       strncat(buf, "UNAFFECTED|", bufsiz - strlen(buf) - 1);
00154    }
00155    /* Get rid of trailing | */
00156    if (ast_strlen_zero(buf))
00157       strcpy(buf, "NONE|");
00158    buf[strlen(buf)-1] = '\0';
00159    return buf;
00160 }

const char* dundi_ie2str ( int  ie  ) 

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

References ies, and 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().

00405 {
00406    int x;
00407    for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
00408       if (ies[x].ie == ie)
00409          return ies[x].name;
00410    }
00411    return "Unknown IE";
00412 }

int dundi_ie_append ( struct dundi_ie_data ied,
unsigned char  ie 
)

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

References dundi_ie_append_raw().

Referenced by dundi_discover().

00655 {
00656    return dundi_ie_append_raw(ied, ie, NULL, 0);
00657 }

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

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

References dundi_ie_append_raw().

00621 {
00622    return dundi_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in));
00623 }

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 593 of file dundi-parser.c.

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

Referenced by dundi_lookup_thread(), and precache_trans().

00594 {
00595    char tmp[256];
00596    int datalen = data ? strlen(data) + 11 : 11;
00597    int x;
00598    unsigned short myw;
00599    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00600       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);
00601       errorf(tmp);
00602       return -1;
00603    }
00604    ied->buf[ied->pos++] = ie;
00605    ied->buf[ied->pos++] = datalen;
00606    for (x=0;x<6;x++)
00607       ied->buf[ied->pos++] = eid->eid[x];
00608    ied->buf[ied->pos++] = protocol;
00609    myw = htons(flags);
00610    memcpy(ied->buf + ied->pos, &myw, 2);
00611    ied->pos += 2;
00612    myw = htons(weight);
00613    memcpy(ied->buf + ied->pos, &myw, 2);
00614    ied->pos += 2;
00615    memcpy(ied->buf + ied->pos, data, datalen-11);
00616    ied->pos += datalen-11;
00617    return 0;
00618 }

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

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

References dundi_ie_append_raw().

00650 {
00651    return dundi_ie_append_raw(ied, ie, &dat, 1);
00652 }

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

Definition at line 537 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(), and handle_command_response().

00538 {
00539    char tmp[256];
00540    int datalen = data ? strlen(data) + 1 : 1;
00541    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00542       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);
00543       errorf(tmp);
00544       return -1;
00545    }
00546    ied->buf[ied->pos++] = ie;
00547    ied->buf[ied->pos++] = datalen;
00548    ied->buf[ied->pos++] = cause;
00549    memcpy(ied->buf + ied->pos, data, datalen-1);
00550    ied->pos += datalen-1;
00551    return 0;
00552 }

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

Definition at line 644 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(), and precache_trans().

00645 {
00646    return dundi_ie_append_raw(ied, ie, (unsigned char *)eid, sizeof(dundi_eid));
00647 }

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

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

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

Referenced by dundi_encrypt().

00574 {
00575    char tmp[256];
00576    datalen += 16;
00577    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00578       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);
00579       errorf(tmp);
00580       return -1;
00581    }
00582    ied->buf[ied->pos++] = ie;
00583    ied->buf[ied->pos++] = datalen;
00584    memcpy(ied->buf + ied->pos, iv, 16);
00585    ied->pos += 16;
00586    if (data) {
00587       memcpy(ied->buf + ied->pos, data, datalen-16);
00588       ied->pos += datalen-16;
00589    }
00590    return 0;
00591 }

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

Definition at line 554 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().

00555 {
00556    char tmp[256];
00557    int datalen = data ? strlen(data) + 2 : 2;
00558    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00559       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);
00560       errorf(tmp);
00561       return -1;
00562    }
00563    ied->buf[ied->pos++] = ie;
00564    ied->buf[ied->pos++] = datalen;
00565    flags = htons(flags);
00566    memcpy(ied->buf + ied->pos, &flags, sizeof(flags));
00567    ied->pos += 2;
00568    memcpy(ied->buf + ied->pos, data, datalen-1);
00569    ied->pos += datalen-2;
00570    return 0;
00571 }

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

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

References dundi_ie_append_raw().

Referenced by dundi_encrypt().

00626 {
00627    unsigned int newval;
00628    newval = htonl(value);
00629    return dundi_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00630 }

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

Definition at line 522 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(), and dundi_ie_append_str().

00523 {
00524    char tmp[256];
00525    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00526       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);
00527       errorf(tmp);
00528       return -1;
00529    }
00530    ied->buf[ied->pos++] = ie;
00531    ied->buf[ied->pos++] = datalen;
00532    memcpy(ied->buf + ied->pos, data, datalen);
00533    ied->pos += datalen;
00534    return 0;
00535 }

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

Definition at line 632 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().

00633 {
00634    unsigned short newval;
00635    newval = htons(value);
00636    return dundi_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00637 }

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

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

References dundi_ie_append_raw().

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

00640 {
00641    return dundi_ie_append_raw(ied, ie, str, strlen(str));
00642 }

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

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

References 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, errorf, ies, len(), and outputf.

Referenced by handle_command_response().

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

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

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

References errorf.

Referenced by load_module().

00665 {
00666    errorf = func;
00667 }

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

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

References outputf.

Referenced by load_module().

00660 {
00661    outputf = func;
00662 }

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

Definition at line 463 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(), and socket_read().

00464 {
00465    char *pref[] = {
00466       "Tx",
00467       "Rx",
00468       "    ETx",
00469       "    Erx" };
00470    char *commands[] = {
00471       "ACK         ",
00472       "DPDISCOVER  ",
00473       "DPRESPONSE  ",
00474       "EIDQUERY    ",
00475       "EIDRESPONSE ",
00476       "PRECACHERQ  ",
00477       "PRECACHERP  ",
00478       "INVALID     ",
00479       "UNKNOWN CMD ",
00480       "NULL        ",
00481       "REQREQ      ",
00482       "REGRESPONSE ",
00483       "CANCEL      ",
00484       "ENCRYPT     ",
00485       "ENCREJ      " };
00486    char class2[20];
00487    char *class;
00488    char subclass2[20];
00489    char *subclass;
00490    char tmp[256];
00491    char retries[20];
00492    if (ntohs(fhi->dtrans) & DUNDI_FLAG_RETRANS)
00493       strcpy(retries, "Yes");
00494    else
00495       strcpy(retries, "No");
00496    if ((ntohs(fhi->strans) & DUNDI_FLAG_RESERVED)) {
00497       /* Ignore frames with high bit set to 1 */
00498       return;
00499    }
00500    if ((fhi->cmdresp & 0x3f) > (int)sizeof(commands)/(int)sizeof(char *)) {
00501       snprintf(class2, (int)sizeof(class2), "(%d?)", fhi->cmdresp);
00502       class = class2;
00503    } else {
00504       class = commands[(int)(fhi->cmdresp & 0x3f)];
00505    }
00506    snprintf(subclass2, (int)sizeof(subclass2), "%02x", fhi->cmdflags);
00507    subclass = subclass2;
00508    snprintf(tmp, (int)sizeof(tmp), 
00509       "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s (%s)\n",
00510       pref[rx],
00511       retries, fhi->oseqno, fhi->iseqno, class, fhi->cmdresp & 0x40 ? "Response" : "Command");
00512    outputf(tmp);
00513    snprintf(tmp, (int)sizeof(tmp), 
00514       "%s     Flags: %s STrans: %5.5d  DTrans: %5.5d [%s:%d]%s\n", (rx > 1) ? "     " : "",
00515       subclass, ntohs(fhi->strans) & ~DUNDI_FLAG_RESERVED, ntohs(fhi->dtrans) & ~DUNDI_FLAG_RETRANS,
00516       ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port),
00517       fhi->cmdresp & 0x80 ? " (Final)" : "");
00518    outputf(tmp);
00519    dump_ies(fhi->ies, rx > 1, datalen);
00520 }

int dundi_str_short_to_eid ( dundi_eid eid,
const char *  s 
)

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

References _dundi_eid::eid.

Referenced by cache_lookup_internal().

00097 {
00098    unsigned int eid_int[6];
00099    int x;
00100    if (sscanf(s, "%2x%2x%2x%2x%2x%2x", &eid_int[0], &eid_int[1], &eid_int[2],
00101        &eid_int[3], &eid_int[4], &eid_int[5]) != 6)
00102          return -1;
00103    for (x = 0; x < 6; x++)
00104       eid->eid[x] = eid_int[x];
00105    return 0;
00106 }

int dundi_str_to_eid ( dundi_eid eid,
const char *  s 
)

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

References _dundi_eid::eid.

Referenced by dundi_do_query(), and set_config().

00085 {
00086    unsigned int eid_int[6];
00087    int x;
00088    if (sscanf(s, "%x:%x:%x:%x:%x:%x", &eid_int[0], &eid_int[1], &eid_int[2],
00089        &eid_int[3], &eid_int[4], &eid_int[5]) != 6)
00090          return -1;
00091    for (x=0;x<6;x++)
00092       eid->eid[x] = eid_int[x];
00093    return 0;
00094 }

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 255 of file dundi-parser.c.

References DUNDI_PROTO_H323, DUNDI_PROTO_IAX, DUNDI_PROTO_NONE, and DUNDI_PROTO_SIP.

Referenced by dump_answer().

00256 {  
00257    switch(proto) {
00258    case DUNDI_PROTO_NONE:
00259       strncpy(buf, "None", bufsiz - 1);
00260       break;
00261    case DUNDI_PROTO_IAX:
00262       strncpy(buf, "IAX", bufsiz - 1);
00263       break;
00264    case DUNDI_PROTO_SIP:
00265       strncpy(buf, "SIP", bufsiz - 1);
00266       break;
00267    case DUNDI_PROTO_H323:
00268       strncpy(buf, "H.323", bufsiz - 1);
00269       break;
00270    default:
00271       snprintf(buf, bufsiz, "Unknown Proto(%d)", proto);
00272    }
00273    buf[bufsiz-1] = '\0';
00274    return buf;
00275 }


Variable Documentation

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

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

struct dundi_ie ies[] [static]

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

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


Generated on Thu Jul 9 13:41:17 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7