Wed Oct 28 15:48:48 2009

Asterisk developer's documentation


dundi-parser.c File Reference

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

#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include "asterisk.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)
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, char *s)
int dundi_str_to_eid (dundi_eid *eid, 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 311 of file dundi-parser.c.

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

00312 {
00313    struct dundi_answer *answer;
00314    char proto[40];
00315    char flags[40];
00316    char eid_str[40];
00317    char tmp[512]="";
00318    if (len >= 10) {
00319       answer = (struct dundi_answer *)(value);
00320       memcpy(tmp, answer->data, (len >= 500) ? 500 : len - 10);
00321       dundi_eid_to_str(eid_str, sizeof(eid_str), &answer->eid);
00322       snprintf(output, maxlen, "[%s] %d <%s/%s> from [%s]", 
00323          dundi_flags2str(flags, sizeof(flags), ntohs(answer->flags)), 
00324          ntohs(answer->weight),
00325          proto2str(answer->protocol, proto, sizeof(proto)), 
00326             tmp, eid_str);
00327    } else
00328       strncpy(output, "Invalid Answer", maxlen - 1);
00329 }

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

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

00244 {
00245    if (len == (int)sizeof(unsigned char))
00246       snprintf(output, maxlen, "%d", *((unsigned char *)value));
00247    else
00248       snprintf(output, maxlen, "Invalid BYTE");
00249 }

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

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

References causes.

00190 {
00191    static char *causes[] = {
00192       "SUCCESS",
00193       "GENERAL",
00194       "DYNAMIC",
00195       "NOAUTH" ,
00196       };
00197    char tmp[256];
00198    char tmp2[256];
00199    int mlen;
00200    unsigned char cause;
00201    if (len < 1) {
00202       strncpy(output, "<invalid contents>", maxlen);
00203       return;
00204    }
00205    cause = *((unsigned char *)value);
00206    memset(tmp2, 0, sizeof(tmp2));
00207    mlen = len - 1;
00208    if (mlen > 255)
00209       mlen = 255;
00210    memcpy(tmp2, value + 1, mlen);
00211    if (cause < sizeof(causes) / sizeof(causes[0])) {
00212       if (len > 1)
00213          snprintf(tmp, sizeof(tmp), "%s: %s", causes[cause], tmp2);
00214       else
00215          snprintf(tmp, sizeof(tmp), "%s", causes[cause]);
00216    } else {
00217       if (len > 1)
00218          snprintf(tmp, sizeof(tmp), "%d: %s", cause, tmp2);
00219       else
00220          snprintf(tmp, sizeof(tmp), "%d", cause);
00221    }
00222    
00223    strncpy(output,tmp, maxlen);
00224    output[maxlen] = '\0';
00225 }

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

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

00137 {
00138    maxlen--;
00139    strncpy(output, "Bypass Caches", maxlen);
00140    output[maxlen] = '\0';
00141 }

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

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

References dundi_eid_to_str().

00144 {
00145    if (len == 6)
00146       dundi_eid_to_str(output, maxlen, (dundi_eid *)value);
00147    else
00148       snprintf(output, maxlen, "Invalid EID len %d", len);
00149 }

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

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

00332 {
00333    char iv[33];
00334    int x;
00335    if ((len > 16) && !(len % 16)) {
00336       /* Build up IV */
00337       for (x=0;x<16;x++) {
00338          snprintf(iv + (x << 1), 3, "%02x", ((unsigned char *)value)[x]);
00339       }
00340       snprintf(output, maxlen, "[IV %s] %d encrypted blocks\n", iv, len / 16);
00341    } else
00342       snprintf(output, maxlen, "Invalid Encrypted Datalen %d", len);
00343 }

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

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

References dundi_hint2str().

00172 {
00173    unsigned short flags;
00174    char tmp[512];
00175    char tmp2[256];
00176    if (len < 2) {
00177       strncpy(output, "<invalid contents>", maxlen);
00178       return;
00179    }
00180    memcpy(&flags, value, sizeof(flags));
00181    flags = ntohs(flags);
00182    memset(tmp, 0, sizeof(tmp));
00183    dundi_hint2str(tmp2, sizeof(tmp2), flags);
00184    snprintf(tmp, sizeof(tmp), "[%s] ", tmp2);
00185    memcpy(tmp + strlen(tmp), value + 2, len - 2);
00186    strncpy(output, tmp, maxlen - 1);
00187 }

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

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

References iax2_ie::dump, DUNDI_IE_ENCDATA, ies, name, and outputf.

00400 {
00401    int ielen;
00402    int ie;
00403    int x;
00404    int found;
00405    char interp[1024];
00406    char tmp[1024];
00407    if (len < 2)
00408       return;
00409    while(len >= 2) {
00410       ie = iedata[0];
00411       ielen = iedata[1];
00412       /* Encrypted data is the remainder */
00413       if (ie == DUNDI_IE_ENCDATA)
00414          ielen = len - 2;
00415       if (ielen + 2> len) {
00416          snprintf(tmp, (int)sizeof(tmp), "Total IE length of %d bytes exceeds remaining frame length of %d bytes\n", ielen + 2, len);
00417          outputf(tmp);
00418          return;
00419       }
00420       found = 0;
00421       for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
00422          if (ies[x].ie == ie) {
00423             if (ies[x].dump) {
00424                ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen);
00425                snprintf(tmp, (int)sizeof(tmp), "   %s%-15.15s : %s\n", (spaces ? "     " : "" ), ies[x].name, interp);
00426                outputf(tmp);
00427             } else {
00428                if (ielen)
00429                   snprintf(interp, (int)sizeof(interp), "%d bytes", ielen);
00430                else
00431                   strcpy(interp, "Present");
00432                snprintf(tmp, (int)sizeof(tmp), "   %s%-15.15s : %s\n", (spaces ? "     " : "" ), ies[x].name, interp);
00433                outputf(tmp);
00434             }
00435             found++;
00436          }
00437       }
00438       if (!found) {
00439          snprintf(tmp, (int)sizeof(tmp), "   %sUnknown IE %03d  : Present\n", (spaces ? "     " : "" ), ie);
00440          outputf(tmp);
00441       }
00442       iedata += (2 + ielen);
00443       len -= (2 + ielen);
00444    }
00445    outputf("\n");
00446 }

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

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

00228 {
00229    if (len == (int)sizeof(unsigned int))
00230       snprintf(output, maxlen, "%lu", (unsigned long)ntohl(*((unsigned int *)value)));
00231    else
00232       snprintf(output, maxlen, "Invalid INT");
00233 }

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

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

00346 {
00347    int x;
00348    unsigned char *u = value;
00349    output[maxlen - 1] = '\0';
00350    strcpy(output, "[ ");
00351    for (x=0;x<len;x++) {
00352       snprintf(output + strlen(output), maxlen - strlen(output) - 1, "%02x ", u[x]);
00353    }
00354    strncat(output + strlen(output), "]", maxlen - strlen(output) - 1);
00355 }

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

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

00236 {
00237    if (len == (int)sizeof(unsigned short))
00238       snprintf(output, maxlen, "%d", ntohs(*((unsigned short *)value)));
00239    else
00240       snprintf(output, maxlen, "Invalid SHORT");
00241 }

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

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

00128 {
00129    maxlen--;
00130    if (maxlen > len)
00131       maxlen = len;
00132    strncpy(output,value, maxlen);
00133    output[maxlen] = '\0';
00134 }

int dundi_eid_cmp ( dundi_eid eid1,
dundi_eid eid2 
)

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

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

References _dundi_eid::eid.

Referenced by append_transaction(), build_peer(), 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().

00058 {
00059    int x;
00060    char *os = s;
00061    if (maxlen < 18) {
00062       if (s && (maxlen > 0))
00063          *s = '\0';
00064    } else {
00065       for (x=0;x<5;x++) {
00066          sprintf(s, "%02x:", eid->eid[x]);
00067          s += 3;
00068       }
00069       sprintf(s, "%02x", eid->eid[5]);
00070    }
00071    return os;
00072 }

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

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

References _dundi_eid::eid.

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

00075 {
00076    int x;
00077    char *os = s;
00078    if (maxlen < 13) {
00079       if (s && (maxlen > 0))
00080          *s = '\0';
00081    } else {
00082       for (x=0;x<6;x++) {
00083          sprintf(s, "%02X", eid->eid[x]);
00084          s += 2;
00085       }
00086    }
00087    return os;
00088 }

int dundi_eid_zero ( dundi_eid eid  ) 

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

References _dundi_eid::eid.

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

00115 {
00116    int x;
00117    for (x=0;x<sizeof(eid->eid) / sizeof(eid->eid[0]);x++)
00118       if (eid->eid[x]) return 0;
00119    return 1;
00120 }

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

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

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

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

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

00152 {
00153    strcpy(buf, "");
00154    buf[bufsiz-1] = '\0';
00155    if (flags & DUNDI_HINT_TTL_EXPIRED) {
00156       strncat(buf, "TTLEXPIRED|", bufsiz - strlen(buf) - 1);
00157    }
00158    if (flags & DUNDI_HINT_DONT_ASK) {
00159       strncat(buf, "DONTASK|", bufsiz - strlen(buf) - 1);
00160    }
00161    if (flags & DUNDI_HINT_UNAFFECTED) {
00162       strncat(buf, "UNAFFECTED|", bufsiz - strlen(buf) - 1);
00163    }
00164    /* Get rid of trailing | */
00165    if (ast_strlen_zero(buf))
00166       strcpy(buf, "NONE|");
00167    buf[strlen(buf)-1] = '\0';
00168    return buf;
00169 }

const char* dundi_ie2str ( int  ie  ) 

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

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

00390 {
00391    int x;
00392    for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
00393       if (ies[x].ie == ie)
00394          return ies[x].name;
00395    }
00396    return "Unknown IE";
00397 }

int dundi_ie_append ( struct dundi_ie_data ied,
unsigned char  ie 
)

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

References dundi_ie_append_raw().

Referenced by dundi_discover().

00641 {
00642    return dundi_ie_append_raw(ied, ie, NULL, 0);
00643 }

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

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

References dundi_ie_append_raw().

00607 {
00608    return dundi_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in));
00609 }

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 579 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().

00580 {
00581    char tmp[256];
00582    int datalen = data ? strlen(data) + 11 : 11;
00583    int x;
00584    unsigned short myw;
00585    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00586       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);
00587       errorf(tmp);
00588       return -1;
00589    }
00590    ied->buf[ied->pos++] = ie;
00591    ied->buf[ied->pos++] = datalen;
00592    for (x=0;x<6;x++)
00593       ied->buf[ied->pos++] = eid->eid[x];
00594    ied->buf[ied->pos++] = protocol;
00595    myw = htons(flags);
00596    memcpy(ied->buf + ied->pos, &myw, 2);
00597    ied->pos += 2;
00598    myw = htons(weight);
00599    memcpy(ied->buf + ied->pos, &myw, 2);
00600    ied->pos += 2;
00601    memcpy(ied->buf + ied->pos, data, datalen-11);
00602    ied->pos += datalen-11;
00603    return 0;
00604 }

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

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

References dundi_ie_append_raw().

Referenced by handle_command_response().

00636 {
00637    return dundi_ie_append_raw(ied, ie, &dat, 1);
00638 }

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

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

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

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

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

00631 {
00632    return dundi_ie_append_raw(ied, ie, (unsigned char *)eid, sizeof(dundi_eid));
00633 }

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

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

00560 {
00561    char tmp[256];
00562    datalen += 16;
00563    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00564       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);
00565       errorf(tmp);
00566       return -1;
00567    }
00568    ied->buf[ied->pos++] = ie;
00569    ied->buf[ied->pos++] = datalen;
00570    memcpy(ied->buf + ied->pos, iv, 16);
00571    ied->pos += 16;
00572    if (data) {
00573       memcpy(ied->buf + ied->pos, data, datalen-16);
00574       ied->pos += datalen-16;
00575    }
00576    return 0;
00577 }

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

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

00541 {
00542    char tmp[256];
00543    int datalen = data ? strlen(data) + 2 : 2;
00544    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00545       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);
00546       errorf(tmp);
00547       return -1;
00548    }
00549    ied->buf[ied->pos++] = ie;
00550    ied->buf[ied->pos++] = datalen;
00551    flags = htons(flags);
00552    memcpy(ied->buf + ied->pos, &flags, sizeof(flags));
00553    ied->pos += 2;
00554    memcpy(ied->buf + ied->pos, data, datalen-1);
00555    ied->pos += datalen-2;
00556    return 0;
00557 }

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

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

References dundi_ie_append_raw().

Referenced by dundi_encrypt().

00612 {
00613    unsigned int newval;
00614    newval = htonl(value);
00615    return dundi_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00616 }

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

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

00509 {
00510    char tmp[256];
00511    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00512       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);
00513       errorf(tmp);
00514       return -1;
00515    }
00516    ied->buf[ied->pos++] = ie;
00517    ied->buf[ied->pos++] = datalen;
00518    memcpy(ied->buf + ied->pos, data, datalen);
00519    ied->pos += datalen;
00520    return 0;
00521 }

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

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

00619 {
00620    unsigned short newval;
00621    newval = htons(value);
00622    return dundi_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00623 }

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

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

References dundi_ie_append_raw().

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

00626 {
00627    return dundi_ie_append_raw(ied, ie, str, strlen(str));
00628 }

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

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

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

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

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

References errorf.

Referenced by load_module().

00651 {
00652    errorf = func;
00653 }

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

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

References outputf.

Referenced by load_module().

00646 {
00647    outputf = func;
00648 }

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

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

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

int dundi_str_short_to_eid ( dundi_eid eid,
char *  s 
)

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

References _dundi_eid::eid.

Referenced by cache_lookup_internal().

00103 {
00104    unsigned int eid_int[6];
00105    int x;
00106    if (sscanf(s, "%2x%2x%2x%2x%2x%2x", &eid_int[0], &eid_int[1], &eid_int[2],
00107        &eid_int[3], &eid_int[4], &eid_int[5]) != 6)
00108          return -1;
00109    for (x=0;x<6;x++)
00110       eid->eid[x] = eid_int[x];
00111    return 0;
00112 }

int dundi_str_to_eid ( dundi_eid eid,
char *  s 
)

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

References _dundi_eid::eid.

Referenced by build_peer(), dundi_do_query(), and set_config().

00091 {
00092    unsigned int eid_int[6];
00093    int x;
00094    if (sscanf(s, "%2x:%2x:%2x:%2x:%2x:%2x", &eid_int[0], &eid_int[1], &eid_int[2],
00095        &eid_int[3], &eid_int[4], &eid_int[5]) != 6)
00096          return -1;
00097    for (x=0;x<6;x++)
00098       eid->eid[x] = eid_int[x];
00099    return 0;
00100 }

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

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

00050 {
00051    fprintf(stderr, "WARNING: %s", str);
00052 }

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

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

00045 {
00046    fputs(str, stdout);
00047 }

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

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

References DUNDI_PROTO_H323, DUNDI_PROTO_IAX, DUNDI_PROTO_NONE, and DUNDI_PROTO_SIP.

Referenced by dump_answer().

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


Variable Documentation

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

struct dundi_ie ies[] [static]

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


Generated on Wed Oct 28 15:48:48 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6