Wed Aug 7 17:16:04 2019

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

Variables

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

Detailed Description

Distributed Universal Number Discovery (DUNDi).

Definition in file dundi-parser.c.


Function Documentation

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

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

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

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

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

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

References ast_copy_string().

00218 {
00219    if (len == (int)sizeof(unsigned char))
00220       snprintf(output, maxlen, "%d", *((unsigned char *)value));
00221    else
00222       ast_copy_string(output, "Invalid BYTE", maxlen);
00223 }

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

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

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

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

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

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

00100 {
00101    snprintf(output, maxlen, "Bypass Caches");
00102 }

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

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

References ast_eid_to_str().

00105 {
00106    if (len == 6)
00107       ast_eid_to_str(output, maxlen, (dundi_eid *)value);
00108    else
00109       snprintf(output, maxlen, "Invalid EID len %d", len);
00110 }

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

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

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

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

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

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

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

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

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

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

Referenced by dundi_showframe().

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

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

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

References ast_copy_string().

00202 {
00203    if (len == (int)sizeof(unsigned int))
00204       snprintf(output, maxlen, "%lu", (unsigned long)ntohl(*((unsigned int *)value)));
00205    else
00206       ast_copy_string(output, "Invalid INT", maxlen);
00207 }

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

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

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

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

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

References ast_copy_string().

00210 {
00211    if (len == (int)sizeof(unsigned short))
00212       snprintf(output, maxlen, "%d", ntohs(*((unsigned short *)value)));
00213    else
00214       ast_copy_string(output, "Invalid SHORT", maxlen);
00215 }

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

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

00092 {
00093    if (maxlen > len + 1)
00094       maxlen = len + 1;
00095 
00096    snprintf(output, maxlen, "%s", (char *) value);
00097 }

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

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

References ast_eid::eid.

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

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

int dundi_eid_zero ( dundi_eid eid  ) 

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

References ARRAY_LEN, and ast_eid::eid.

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

00084 {
00085    int x;
00086    for (x = 0; x < ARRAY_LEN(eid->eid); x++)
00087       if (eid->eid[x]) return 0;
00088    return 1;
00089 }

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

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

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

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

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

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

const char* dundi_ie2str ( int  ie  ) 

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

References ARRAY_LEN, infoelts, and dundi_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().

00375 {
00376    int x;
00377    for (x = 0; x < ARRAY_LEN(infoelts); x++) {
00378       if (infoelts[x].ie == ie)
00379          return infoelts[x].name;
00380    }
00381    return "Unknown IE";
00382 }

int dundi_ie_append ( struct dundi_ie_data ied,
unsigned char  ie 
)

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

References dundi_ie_append_raw().

Referenced by dundi_discover().

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

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

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

References dundi_ie_append_raw().

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

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

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

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

Referenced by dundi_lookup_thread(), and precache_trans().

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

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

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

References dundi_ie_append_raw().

Referenced by handle_command_response().

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

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

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

00500 {
00501    char tmp[256];
00502    int datalen = data ? strlen(data) + 1 : 1;
00503    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00504       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);
00505       errorf(tmp);
00506       return -1;
00507    }
00508    ied->buf[ied->pos++] = ie;
00509    ied->buf[ied->pos++] = datalen;
00510    ied->buf[ied->pos++] = cause;
00511    if (data) {
00512       memcpy(ied->buf + ied->pos, data, datalen-1);
00513       ied->pos += datalen-1;
00514    }
00515    return 0;
00516 }

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

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

References dundi_ie_append_raw().

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

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

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

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

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

Referenced by dundi_encrypt(), and handle_command_response().

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

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

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

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

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

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

References dundi_ie_append_raw().

Referenced by dundi_encrypt().

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

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

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

00485 {
00486    char tmp[256];
00487    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00488       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);
00489       errorf(tmp);
00490       return -1;
00491    }
00492    ied->buf[ied->pos++] = ie;
00493    ied->buf[ied->pos++] = datalen;
00494    memcpy(ied->buf + ied->pos, data, datalen);
00495    ied->pos += datalen;
00496    return 0;
00497 }

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

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

References dundi_ie_append_raw().

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

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

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

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

References dundi_ie_append_raw().

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

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

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

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

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

Referenced by handle_command_response().

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

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

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

References errorf.

Referenced by load_module().

00631 {
00632    errorf = func;
00633 }

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

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

References outputf.

Referenced by load_module().

00626 {
00627    outputf = func;
00628 }

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

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

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

int dundi_str_short_to_eid ( dundi_eid eid,
const char *  s 
)

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

References ast_eid::eid.

Referenced by cache_lookup_internal().

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

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

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

00048 {
00049    fprintf(stderr, "WARNING: %s", str);
00050 }

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

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

00043 {
00044    fputs(str, stdout);
00045 }

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

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

References DUNDI_PROTO_H323, DUNDI_PROTO_IAX, DUNDI_PROTO_NONE, and DUNDI_PROTO_SIP.

Referenced by dump_answer().

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


Variable Documentation

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

Referenced by dump_ies(), and dundi_ie2str().

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

Generated on 7 Aug 2019 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1