Sat Aug 6 00:39:55 2011

Asterisk developer's documentation


dundi-parser.c File Reference

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

#include "asterisk.h"
#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/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, 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_eid_to_str(), dundi_flags2str(), dundi_answer::flags, and proto2str().

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(), and ast_frame::flags.

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 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 
)

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

00123 {
00124    return memcmp(eid1, eid2, sizeof(dundi_eid));
00125 }

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

References dundi_ie_append_raw().

Referenced by dundi_discover().

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

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

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

References dundi_ie_append_raw().

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

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

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

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

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

References dundi_ie_append_raw().

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

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

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_answer_entity(), dundi_answer_query(), dundi_lookup_thread(), and handle_command_response().

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

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

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

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

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

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

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

Referenced by dundi_encrypt().

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

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

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_lookup_thread(), dundi_query_thread(), and precache_trans().

00540 {
00541    char tmp[256];
00542    int datalen = data ? strlen(data) + 2 : 2;
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    flags = htons(flags);
00551    memcpy(ied->buf + ied->pos, &flags, sizeof(flags));
00552    ied->pos += 2;
00553    memcpy(ied->buf + ied->pos, data, datalen-1);
00554    ied->pos += datalen-2;
00555    return 0;
00556 }

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

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

References dundi_ie_append_raw().

Referenced by dundi_encrypt().

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

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

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

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

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

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

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

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

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

References dundi_ie_append_raw().

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

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

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

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

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

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

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

References errorf.

Referenced by load_module().

00650 {
00651    errorf = func;
00652 }

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

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

References outputf.

Referenced by load_module().

00645 {
00646    outputf = func;
00647 }

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(), 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    if (ntohs(fhi->dtrans) & DUNDI_FLAG_RETRANS)
00478       strcpy(retries, "Yes");
00479    else
00480       strcpy(retries, "No");
00481    if ((ntohs(fhi->strans) & DUNDI_FLAG_RESERVED)) {
00482       /* Ignore frames with high bit set to 1 */
00483       return;
00484    }
00485    if ((fhi->cmdresp & 0x3f) > (int)sizeof(commands)/(int)sizeof(char *)) {
00486       snprintf(class2, (int)sizeof(class2), "(%d?)", fhi->cmdresp);
00487       class = class2;
00488    } else {
00489       class = commands[(int)(fhi->cmdresp & 0x3f)];
00490    }
00491    snprintf(subclass2, (int)sizeof(subclass2), "%02x", fhi->cmdflags);
00492    subclass = subclass2;
00493    snprintf(tmp, (int)sizeof(tmp), 
00494       "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s (%s)\n",
00495       pref[rx],
00496       retries, fhi->oseqno, fhi->iseqno, class, fhi->cmdresp & 0x40 ? "Response" : "Command");
00497    outputf(tmp);
00498    snprintf(tmp, (int)sizeof(tmp), 
00499       "%s     Flags: %s STrans: %5.5d  DTrans: %5.5d [%s:%d]%s\n", (rx > 1) ? "     " : "",
00500       subclass, ntohs(fhi->strans) & ~DUNDI_FLAG_RESERVED, ntohs(fhi->dtrans) & ~DUNDI_FLAG_RETRANS,
00501       ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port),
00502       fhi->cmdresp & 0x80 ? " (Final)" : "");
00503    outputf(tmp);
00504    dump_ies(fhi->ies, rx > 1, datalen);
00505 }

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 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]

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

struct dundi_ie ies[] [static]

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

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


Generated on Sat Aug 6 00:39:55 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7