#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 |
Definition in file dundi-parser.c.
static void dump_answer | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 281 of file dundi-parser.c.
References ast_eid_to_str(), dundi_answer::data, dundi_flags2str(), dundi_answer::flags, and proto2str().
00282 { 00283 struct dundi_answer *answer; 00284 char proto[40]; 00285 char flags[40]; 00286 char eid_str[40]; 00287 char tmp[512]=""; 00288 int datalen; 00289 00290 if (len < sizeof(*answer)) { 00291 snprintf(output, maxlen, "Invalid Answer"); 00292 return; 00293 } 00294 00295 answer = (struct dundi_answer *)(value); 00296 00297 datalen = len - offsetof(struct dundi_answer, data); 00298 if (datalen > sizeof(tmp) - 1) 00299 datalen = sizeof(tmp) - 1; 00300 00301 memcpy(tmp, answer->data, datalen); 00302 tmp[datalen] = '\0'; 00303 00304 ast_eid_to_str(eid_str, sizeof(eid_str), &answer->eid); 00305 snprintf(output, maxlen, "[%s] %d <%s/%s> from [%s]", 00306 dundi_flags2str(flags, sizeof(flags), ntohs(answer->flags)), 00307 ntohs(answer->weight), 00308 proto2str(answer->protocol, proto, sizeof(proto)), 00309 tmp, eid_str); 00310 }
static void dump_byte | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 213 of file dundi-parser.c.
References ast_copy_string().
00214 { 00215 if (len == (int)sizeof(unsigned char)) 00216 snprintf(output, maxlen, "%d", *((unsigned char *)value)); 00217 else 00218 ast_copy_string(output, "Invalid BYTE", maxlen); 00219 }
static void dump_cause | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 156 of file dundi-parser.c.
References ARRAY_LEN, ast_strlen_zero(), cause, dundi_cause::causecode, causes, and desc.
00157 { 00158 static const char * const causes[] = { 00159 "SUCCESS", 00160 "GENERAL", 00161 "DYNAMIC", 00162 "NOAUTH" , 00163 }; 00164 char tmp2[256]; 00165 struct dundi_cause *cause; 00166 int datalen; 00167 int causecode; 00168 00169 if (len < sizeof(*cause)) { 00170 snprintf(output, maxlen, "<invalid contents>"); 00171 return; 00172 } 00173 00174 cause = (struct dundi_cause*) value; 00175 causecode = cause->causecode; 00176 00177 datalen = len - offsetof(struct dundi_cause, desc); 00178 if (datalen > sizeof(tmp2) - 1) 00179 datalen = sizeof(tmp2) - 1; 00180 00181 memcpy(tmp2, cause->desc, datalen); 00182 tmp2[datalen] = '\0'; 00183 00184 if (causecode < ARRAY_LEN(causes)) { 00185 if (ast_strlen_zero(tmp2)) 00186 snprintf(output, maxlen, "%s", causes[causecode]); 00187 else 00188 snprintf(output, maxlen, "%s: %s", causes[causecode], tmp2); 00189 } else { 00190 if (ast_strlen_zero(tmp2)) 00191 snprintf(output, maxlen, "%d", causecode); 00192 else 00193 snprintf(output, maxlen, "%d: %s", causecode, tmp2); 00194 } 00195 }
static void dump_cbypass | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
static void dump_eid | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 100 of file dundi-parser.c.
References ast_eid_to_str().
00101 { 00102 if (len == 6) 00103 ast_eid_to_str(output, maxlen, (dundi_eid *)value); 00104 else 00105 snprintf(output, maxlen, "Invalid EID len %d", len); 00106 }
static void dump_encrypted | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 312 of file dundi-parser.c.
00313 { 00314 char iv[33]; 00315 int x; 00316 if ((len > 16) && !(len % 16)) { 00317 /* Build up IV */ 00318 for (x=0;x<16;x++) { 00319 snprintf(iv + (x << 1), 3, "%02x", ((unsigned char *)value)[x]); 00320 } 00321 snprintf(output, maxlen, "[IV %s] %d encrypted blocks\n", iv, len / 16); 00322 } else 00323 snprintf(output, maxlen, "Invalid Encrypted Datalen %d", len); 00324 }
static void dump_hint | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 128 of file dundi-parser.c.
References ast_strlen_zero(), dundi_hint::data, ast_frame::datalen, and dundi_hint2str().
00129 { 00130 char tmp2[256]; 00131 char tmp3[256]; 00132 int datalen; 00133 struct dundi_hint *hint; 00134 if (len < sizeof(*hint)) { 00135 snprintf(output, maxlen, "<invalid contents>"); 00136 return; 00137 } 00138 00139 hint = (struct dundi_hint *) value;; 00140 00141 datalen = len - offsetof(struct dundi_hint, data); 00142 if (datalen > sizeof(tmp3) - 1) 00143 datalen = sizeof(tmp3) - 1; 00144 00145 memcpy(tmp3, hint->data, datalen); 00146 tmp3[datalen] = '\0'; 00147 00148 dundi_hint2str(tmp2, sizeof(tmp2), ntohs(hint->flags)); 00149 00150 if (ast_strlen_zero(tmp3)) 00151 snprintf(output, maxlen, "[%s]", tmp2); 00152 else 00153 snprintf(output, maxlen, "[%s] %s", tmp2, tmp3); 00154 }
static void dump_ies | ( | unsigned char * | iedata, | |
int | spaces, | |||
int | len | |||
) | [static] |
Definition at line 380 of file dundi-parser.c.
References ARRAY_LEN, iax2_ie::dump, DUNDI_IE_ENCDATA, infoelts, name, and outputf.
00381 { 00382 int ielen; 00383 int ie; 00384 int x; 00385 int found; 00386 char interp[1024]; 00387 char tmp[1024]; 00388 if (len < 2) 00389 return; 00390 while(len >= 2) { 00391 ie = iedata[0]; 00392 ielen = iedata[1]; 00393 /* Encrypted data is the remainder */ 00394 if (ie == DUNDI_IE_ENCDATA) 00395 ielen = len - 2; 00396 if (ielen + 2> len) { 00397 snprintf(tmp, (int)sizeof(tmp), "Total IE length of %d bytes exceeds remaining frame length of %d bytes\n", ielen + 2, len); 00398 outputf(tmp); 00399 return; 00400 } 00401 found = 0; 00402 for (x = 0; x < ARRAY_LEN(infoelts); x++) { 00403 if (infoelts[x].ie == ie) { 00404 if (infoelts[x].dump) { 00405 infoelts[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen); 00406 snprintf(tmp, (int)sizeof(tmp), " %s%-15.15s : %s\n", (spaces ? " " : "" ), infoelts[x].name, interp); 00407 outputf(tmp); 00408 } else { 00409 if (ielen) 00410 snprintf(interp, (int)sizeof(interp), "%d bytes", ielen); 00411 else 00412 strcpy(interp, "Present"); 00413 snprintf(tmp, (int)sizeof(tmp), " %s%-15.15s : %s\n", (spaces ? " " : "" ), infoelts[x].name, interp); 00414 outputf(tmp); 00415 } 00416 found++; 00417 } 00418 } 00419 if (!found) { 00420 snprintf(tmp, (int)sizeof(tmp), " %sUnknown IE %03d : Present\n", (spaces ? " " : "" ), ie); 00421 outputf(tmp); 00422 } 00423 iedata += (2 + ielen); 00424 len -= (2 + ielen); 00425 } 00426 outputf("\n"); 00427 }
static void dump_int | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 197 of file dundi-parser.c.
References ast_copy_string().
00198 { 00199 if (len == (int)sizeof(unsigned int)) 00200 snprintf(output, maxlen, "%lu", (unsigned long)ntohl(*((unsigned int *)value))); 00201 else 00202 ast_copy_string(output, "Invalid INT", maxlen); 00203 }
static void dump_raw | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 326 of file dundi-parser.c.
00327 { 00328 int x; 00329 unsigned char *u = value; 00330 output[maxlen - 1] = '\0'; 00331 strcpy(output, "[ "); 00332 for (x=0;x<len;x++) { 00333 snprintf(output + strlen(output), maxlen - strlen(output) - 1, "%02x ", u[x]); 00334 } 00335 strncat(output + strlen(output), "]", maxlen - strlen(output) - 1); 00336 }
static void dump_short | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 205 of file dundi-parser.c.
References ast_copy_string().
00206 { 00207 if (len == (int)sizeof(unsigned short)) 00208 snprintf(output, maxlen, "%d", ntohs(*((unsigned short *)value))); 00209 else 00210 ast_copy_string(output, "Invalid SHORT", maxlen); 00211 }
static void dump_string | ( | char * | output, | |
int | maxlen, | |||
void * | value, | |||
int | len | |||
) | [static] |
Definition at line 87 of file dundi-parser.c.
00088 { 00089 if (maxlen > len + 1) 00090 maxlen = len + 1; 00091 00092 snprintf(output, maxlen, "%s", (char *) value); 00093 }
char* dundi_eid_to_str_short | ( | char * | s, | |
int | maxlen, | |||
dundi_eid * | eid | |||
) |
Definition at line 51 of file dundi-parser.c.
References ast_eid::eid.
Referenced by cache_lookup(), cache_save(), cache_save_hint(), and handle_command_response().
00052 { 00053 int x; 00054 char *os = s; 00055 if (maxlen < 13) { 00056 if (s && (maxlen > 0)) 00057 *s = '\0'; 00058 } else { 00059 for (x=0;x<6;x++) { 00060 sprintf(s, "%02X", eid->eid[x]); 00061 s += 2; 00062 } 00063 } 00064 return os; 00065 }
int dundi_eid_zero | ( | dundi_eid * | eid | ) |
Definition at line 79 of file dundi-parser.c.
References ARRAY_LEN, and ast_eid::eid.
Referenced by build_transactions(), dundi_discover(), dundi_query(), dundi_show_requests(), and precache_trans().
00080 { 00081 int x; 00082 for (x = 0; x < ARRAY_LEN(eid->eid); x++) 00083 if (eid->eid[x]) return 0; 00084 return 1; 00085 }
char* dundi_flags2str | ( | char * | buf, | |
int | bufsiz, | |||
int | flags | |||
) |
Definition at line 243 of file dundi-parser.c.
References ast_strlen_zero(), DUNDI_FLAG_CANMATCH, DUNDI_FLAG_COMMERCIAL, DUNDI_FLAG_EXISTS, DUNDI_FLAG_IGNOREPAT, DUNDI_FLAG_MATCHMORE, DUNDI_FLAG_MOBILE, DUNDI_FLAG_NOCOMUNSOLICIT, DUNDI_FLAG_NOUNSOLICITED, and DUNDI_FLAG_RESIDENTIAL.
Referenced by cache_lookup_internal(), dump_answer(), dundi_do_lookup(), and dundi_show_mappings().
00244 { 00245 strcpy(buf, ""); 00246 buf[bufsiz-1] = '\0'; 00247 if (flags & DUNDI_FLAG_EXISTS) { 00248 strncat(buf, "EXISTS|", bufsiz - strlen(buf) - 1); 00249 } 00250 if (flags & DUNDI_FLAG_MATCHMORE) { 00251 strncat(buf, "MATCHMORE|", bufsiz - strlen(buf) - 1); 00252 } 00253 if (flags & DUNDI_FLAG_CANMATCH) { 00254 strncat(buf, "CANMATCH|", bufsiz - strlen(buf) - 1); 00255 } 00256 if (flags & DUNDI_FLAG_IGNOREPAT) { 00257 strncat(buf, "IGNOREPAT|", bufsiz - strlen(buf) - 1); 00258 } 00259 if (flags & DUNDI_FLAG_RESIDENTIAL) { 00260 strncat(buf, "RESIDENCE|", bufsiz - strlen(buf) - 1); 00261 } 00262 if (flags & DUNDI_FLAG_COMMERCIAL) { 00263 strncat(buf, "COMMERCIAL|", bufsiz - strlen(buf) - 1); 00264 } 00265 if (flags & DUNDI_FLAG_MOBILE) { 00266 strncat(buf, "MOBILE", bufsiz - strlen(buf) - 1); 00267 } 00268 if (flags & DUNDI_FLAG_NOUNSOLICITED) { 00269 strncat(buf, "NOUNSLCTD|", bufsiz - strlen(buf) - 1); 00270 } 00271 if (flags & DUNDI_FLAG_NOCOMUNSOLICIT) { 00272 strncat(buf, "NOCOMUNSLTD|", bufsiz - strlen(buf) - 1); 00273 } 00274 /* Get rid of trailing | */ 00275 if (ast_strlen_zero(buf)) 00276 strcpy(buf, "NONE|"); 00277 buf[strlen(buf)-1] = '\0'; 00278 return buf; 00279 }
char* dundi_hint2str | ( | char * | buf, | |
int | bufsiz, | |||
int | flags | |||
) |
Definition at line 108 of file dundi-parser.c.
References ast_strlen_zero(), DUNDI_HINT_DONT_ASK, DUNDI_HINT_TTL_EXPIRED, and DUNDI_HINT_UNAFFECTED.
Referenced by dump_hint().
00109 { 00110 strcpy(buf, ""); 00111 buf[bufsiz-1] = '\0'; 00112 if (flags & DUNDI_HINT_TTL_EXPIRED) { 00113 strncat(buf, "TTLEXPIRED|", bufsiz - strlen(buf) - 1); 00114 } 00115 if (flags & DUNDI_HINT_DONT_ASK) { 00116 strncat(buf, "DONTASK|", bufsiz - strlen(buf) - 1); 00117 } 00118 if (flags & DUNDI_HINT_UNAFFECTED) { 00119 strncat(buf, "UNAFFECTED|", bufsiz - strlen(buf) - 1); 00120 } 00121 /* Get rid of trailing | */ 00122 if (ast_strlen_zero(buf)) 00123 strcpy(buf, "NONE|"); 00124 buf[strlen(buf)-1] = '\0'; 00125 return buf; 00126 }
const char* dundi_ie2str | ( | int | ie | ) |
Definition at line 370 of file dundi-parser.c.
References ARRAY_LEN, infoelts, and iax2_ie::name.
Referenced by dundi_ie_append_answer(), dundi_ie_append_cause(), dundi_ie_append_encdata(), dundi_ie_append_hint(), dundi_ie_append_raw(), and dundi_parse_ies().
00371 { 00372 int x; 00373 for (x = 0; x < ARRAY_LEN(infoelts); x++) { 00374 if (infoelts[x].ie == ie) 00375 return infoelts[x].name; 00376 } 00377 return "Unknown IE"; 00378 }
int dundi_ie_append | ( | struct dundi_ie_data * | ied, | |
unsigned char | ie | |||
) |
Definition at line 620 of file dundi-parser.c.
References dundi_ie_append_raw().
Referenced by dundi_discover().
00621 { 00622 return dundi_ie_append_raw(ied, ie, NULL, 0); 00623 }
int dundi_ie_append_addr | ( | struct dundi_ie_data * | ied, | |
unsigned char | ie, | |||
struct sockaddr_in * | sin | |||
) |
Definition at line 586 of file dundi-parser.c.
References dundi_ie_append_raw().
00587 { 00588 return dundi_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in)); 00589 }
int dundi_ie_append_answer | ( | struct dundi_ie_data * | ied, | |
unsigned char | ie, | |||
dundi_eid * | eid, | |||
unsigned char | protocol, | |||
unsigned short | flags, | |||
unsigned short | weight, | |||
char * | data | |||
) |
Definition at line 559 of file dundi-parser.c.
References dundi_ie_data::buf, dundi_ie2str(), ast_eid::eid, errorf, and dundi_ie_data::pos.
Referenced by dundi_lookup_thread(), and precache_trans().
00560 { 00561 char tmp[256]; 00562 int datalen = data ? strlen(data) + 11 : 11; 00563 int x; 00564 unsigned short myw; 00565 if (datalen > ((int)sizeof(ied->buf) - ied->pos)) { 00566 snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", dundi_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos); 00567 errorf(tmp); 00568 return -1; 00569 } 00570 ied->buf[ied->pos++] = ie; 00571 ied->buf[ied->pos++] = datalen; 00572 for (x=0;x<6;x++) 00573 ied->buf[ied->pos++] = eid->eid[x]; 00574 ied->buf[ied->pos++] = protocol; 00575 myw = htons(flags); 00576 memcpy(ied->buf + ied->pos, &myw, 2); 00577 ied->pos += 2; 00578 myw = htons(weight); 00579 memcpy(ied->buf + ied->pos, &myw, 2); 00580 ied->pos += 2; 00581 memcpy(ied->buf + ied->pos, data, datalen-11); 00582 ied->pos += datalen-11; 00583 return 0; 00584 }
int dundi_ie_append_byte | ( | struct dundi_ie_data * | ied, | |
unsigned char | ie, | |||
unsigned char | dat | |||
) |
Definition at line 615 of file dundi-parser.c.
References dundi_ie_append_raw().
00616 { 00617 return dundi_ie_append_raw(ied, ie, &dat, 1); 00618 }
int dundi_ie_append_cause | ( | struct dundi_ie_data * | ied, | |
unsigned char | ie, | |||
unsigned char | cause, | |||
char * | data | |||
) |
Definition at line 503 of file dundi-parser.c.
References dundi_ie_data::buf, dundi_ie2str(), errorf, and dundi_ie_data::pos.
Referenced by dundi_answer_entity(), dundi_answer_query(), dundi_lookup_thread(), and handle_command_response().
00504 { 00505 char tmp[256]; 00506 int datalen = data ? strlen(data) + 1 : 1; 00507 if (datalen > ((int)sizeof(ied->buf) - ied->pos)) { 00508 snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", dundi_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos); 00509 errorf(tmp); 00510 return -1; 00511 } 00512 ied->buf[ied->pos++] = ie; 00513 ied->buf[ied->pos++] = datalen; 00514 ied->buf[ied->pos++] = cause; 00515 memcpy(ied->buf + ied->pos, data, datalen-1); 00516 ied->pos += datalen-1; 00517 return 0; 00518 }
int dundi_ie_append_eid | ( | struct dundi_ie_data * | ied, | |
unsigned char | ie, | |||
dundi_eid * | eid | |||
) |
Definition at line 610 of file dundi-parser.c.
References dundi_ie_append_raw().
Referenced by do_register(), dundi_discover(), dundi_encrypt(), dundi_ie_append_eid_appropriately(), dundi_query(), 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().
00540 { 00541 char tmp[256]; 00542 datalen += 16; 00543 if (datalen > ((int)sizeof(ied->buf) - ied->pos)) { 00544 snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", dundi_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos); 00545 errorf(tmp); 00546 return -1; 00547 } 00548 ied->buf[ied->pos++] = ie; 00549 ied->buf[ied->pos++] = datalen; 00550 memcpy(ied->buf + ied->pos, iv, 16); 00551 ied->pos += 16; 00552 if (data) { 00553 memcpy(ied->buf + ied->pos, data, datalen-16); 00554 ied->pos += datalen-16; 00555 } 00556 return 0; 00557 }
int dundi_ie_append_hint | ( | struct dundi_ie_data * | ied, | |
unsigned char | ie, | |||
unsigned short | flags, | |||
char * | data | |||
) |
Definition at line 520 of file dundi-parser.c.
References dundi_ie_data::buf, dundi_ie2str(), errorf, and dundi_ie_data::pos.
Referenced by dundi_lookup_thread(), dundi_query_thread(), and precache_trans().
00521 { 00522 char tmp[256]; 00523 int datalen = data ? strlen(data) + 2 : 2; 00524 if (datalen > ((int)sizeof(ied->buf) - ied->pos)) { 00525 snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", dundi_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos); 00526 errorf(tmp); 00527 return -1; 00528 } 00529 ied->buf[ied->pos++] = ie; 00530 ied->buf[ied->pos++] = datalen; 00531 flags = htons(flags); 00532 memcpy(ied->buf + ied->pos, &flags, sizeof(flags)); 00533 ied->pos += 2; 00534 memcpy(ied->buf + ied->pos, data, datalen-1); 00535 ied->pos += datalen-2; 00536 return 0; 00537 }
int dundi_ie_append_int | ( | struct dundi_ie_data * | ied, | |
unsigned char | ie, | |||
unsigned int | value | |||
) |
Definition at line 591 of file dundi-parser.c.
References dundi_ie_append_raw().
Referenced by dundi_encrypt().
00592 { 00593 unsigned int newval; 00594 newval = htonl(value); 00595 return dundi_ie_append_raw(ied, ie, &newval, (int)sizeof(newval)); 00596 }
int dundi_ie_append_raw | ( | struct dundi_ie_data * | ied, | |
unsigned char | ie, | |||
void * | data, | |||
int | datalen | |||
) |
Definition at line 488 of file dundi-parser.c.
References dundi_ie_data::buf, dundi_ie2str(), errorf, and dundi_ie_data::pos.
Referenced by dundi_encrypt(), dundi_ie_append(), dundi_ie_append_addr(), dundi_ie_append_byte(), dundi_ie_append_eid(), dundi_ie_append_int(), dundi_ie_append_short(), and dundi_ie_append_str().
00489 { 00490 char tmp[256]; 00491 if (datalen > ((int)sizeof(ied->buf) - ied->pos)) { 00492 snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", dundi_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos); 00493 errorf(tmp); 00494 return -1; 00495 } 00496 ied->buf[ied->pos++] = ie; 00497 ied->buf[ied->pos++] = datalen; 00498 memcpy(ied->buf + ied->pos, data, datalen); 00499 ied->pos += datalen; 00500 return 0; 00501 }
int dundi_ie_append_short | ( | struct dundi_ie_data * | ied, | |
unsigned char | ie, | |||
unsigned short | value | |||
) |
Definition at line 598 of file dundi-parser.c.
References dundi_ie_append_raw().
Referenced by do_register(), dundi_discover(), dundi_lookup_thread(), dundi_query(), handle_command_response(), and precache_trans().
00599 { 00600 unsigned short newval; 00601 newval = htons(value); 00602 return dundi_ie_append_raw(ied, ie, &newval, (int)sizeof(newval)); 00603 }
int dundi_ie_append_str | ( | struct dundi_ie_data * | ied, | |
unsigned char | ie, | |||
char * | str | |||
) |
Definition at line 605 of file dundi-parser.c.
References dundi_ie_append_raw().
Referenced by dundi_discover(), dundi_query(), dundi_query_thread(), and precache_trans().
00606 { 00607 return dundi_ie_append_raw(ied, ie, str, strlen(str)); 00608 }
int dundi_parse_ies | ( | struct dundi_ies * | ies, | |
unsigned char * | data, | |||
int | datalen | |||
) |
Definition at line 635 of file dundi-parser.c.
References dundi_ies::anscount, dundi_ies::answers, dundi_ies::called_context, dundi_ies::called_number, dundi_ies::cause, dundi_ies::causestr, dundi_ies::cbypass, dundi_ie2str(), DUNDI_IE_ANSWER, DUNDI_IE_CACHEBYPASS, DUNDI_IE_CALLED_CONTEXT, DUNDI_IE_CALLED_NUMBER, DUNDI_IE_CAUSE, DUNDI_IE_COUNTRY, DUNDI_IE_DEPARTMENT, DUNDI_IE_EID, DUNDI_IE_EID_DIRECT, DUNDI_IE_EMAIL, DUNDI_IE_ENCDATA, DUNDI_IE_EXPIRATION, DUNDI_IE_HINT, DUNDI_IE_IPADDR, DUNDI_IE_KEYCRC32, DUNDI_IE_LOCALITY, DUNDI_IE_ORGANIZATION, DUNDI_IE_PHONE, DUNDI_IE_REQEID, DUNDI_IE_SHAREDKEY, DUNDI_IE_SIGNATURE, DUNDI_IE_STATE_PROV, DUNDI_IE_TTL, DUNDI_IE_UNKNOWN, DUNDI_IE_VERSION, DUNDI_MAX_ANSWERS, DUNDI_MAX_STACK, dundi_ies::eid_direct, dundi_ies::eidcount, dundi_ies::eids, dundi_ies::encblock, dundi_ies::enclen, dundi_ies::encsharedkey, dundi_ies::encsig, errorf, dundi_ies::expiration, dundi_ies::hint, dundi_ies::keycrc32, len(), outputf, dundi_ies::q_country, dundi_ies::q_dept, dundi_ies::q_email, dundi_ies::q_ipaddr, dundi_ies::q_locality, dundi_ies::q_org, dundi_ies::q_phone, dundi_ies::q_stateprov, dundi_ies::reqeid, dundi_ies::ttl, dundi_ies::unknowncmd, and dundi_ies::version.
Referenced by handle_command_response().
00636 { 00637 /* Parse data into information elements */ 00638 int len; 00639 int ie; 00640 char tmp[256]; 00641 memset(ies, 0, (int)sizeof(struct dundi_ies)); 00642 ies->ttl = -1; 00643 ies->expiration = -1; 00644 ies->unknowncmd = -1; 00645 ies->cause = -1; 00646 while(datalen >= 2) { 00647 ie = data[0]; 00648 len = data[1]; 00649 if (len > datalen - 2) { 00650 errorf("Information element length exceeds message size\n"); 00651 return -1; 00652 } 00653 switch(ie) { 00654 case DUNDI_IE_EID: 00655 case DUNDI_IE_EID_DIRECT: 00656 if (len != (int)sizeof(dundi_eid)) { 00657 errorf("Improper entity identifer, expecting 6 bytes!\n"); 00658 } else if (ies->eidcount < DUNDI_MAX_STACK) { 00659 ies->eids[ies->eidcount] = (dundi_eid *)(data + 2); 00660 ies->eid_direct[ies->eidcount] = (ie == DUNDI_IE_EID_DIRECT); 00661 ies->eidcount++; 00662 } else 00663 errorf("Too many entities in stack!\n"); 00664 break; 00665 case DUNDI_IE_REQEID: 00666 if (len != (int)sizeof(dundi_eid)) { 00667 errorf("Improper requested entity identifer, expecting 6 bytes!\n"); 00668 } else 00669 ies->reqeid = (dundi_eid *)(data + 2); 00670 break; 00671 case DUNDI_IE_CALLED_CONTEXT: 00672 ies->called_context = (char *)data + 2; 00673 break; 00674 case DUNDI_IE_CALLED_NUMBER: 00675 ies->called_number = (char *)data + 2; 00676 break; 00677 case DUNDI_IE_ANSWER: 00678 if (len < sizeof(struct dundi_answer)) { 00679 snprintf(tmp, (int)sizeof(tmp), "Answer expected to be >=%d bytes long but was %d\n", (int)sizeof(struct dundi_answer), len); 00680 errorf(tmp); 00681 } else { 00682 if (ies->anscount < DUNDI_MAX_ANSWERS) 00683 ies->answers[ies->anscount++]= (struct dundi_answer *)(data + 2); 00684 else 00685 errorf("Ignoring extra answers!\n"); 00686 } 00687 break; 00688 case DUNDI_IE_TTL: 00689 if (len != (int)sizeof(unsigned short)) { 00690 snprintf(tmp, (int)sizeof(tmp), "Expecting ttl to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00691 errorf(tmp); 00692 } else 00693 ies->ttl = ntohs(*((unsigned short *)(data + 2))); 00694 break; 00695 case DUNDI_IE_VERSION: 00696 if (len != (int)sizeof(unsigned short)) { 00697 snprintf(tmp, (int)sizeof(tmp), "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00698 errorf(tmp); 00699 } else 00700 ies->version = ntohs(*((unsigned short *)(data + 2))); 00701 break; 00702 case DUNDI_IE_EXPIRATION: 00703 if (len != (int)sizeof(unsigned short)) { 00704 snprintf(tmp, (int)sizeof(tmp), "Expecting expiration to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); 00705 errorf(tmp); 00706 } else 00707 ies->expiration = ntohs(*((unsigned short *)(data + 2))); 00708 break; 00709 case DUNDI_IE_KEYCRC32: 00710 if (len != (int)sizeof(unsigned int)) { 00711 snprintf(tmp, (int)sizeof(tmp), "Expecting expiration to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len); 00712 errorf(tmp); 00713 } else 00714 ies->keycrc32 = ntohl(*((unsigned int *)(data + 2))); 00715 break; 00716 case DUNDI_IE_UNKNOWN: 00717 if (len == 1) 00718 ies->unknowncmd = data[2]; 00719 else { 00720 snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len); 00721 errorf(tmp); 00722 } 00723 break; 00724 case DUNDI_IE_CAUSE: 00725 if (len >= 1) { 00726 ies->cause = data[2]; 00727 ies->causestr = (char *)data + 3; 00728 } else { 00729 snprintf(tmp, (int)sizeof(tmp), "Expected at least one byte cause, but was %d long\n", len); 00730 errorf(tmp); 00731 } 00732 break; 00733 case DUNDI_IE_HINT: 00734 if (len >= 2) { 00735 ies->hint = (struct dundi_hint *)(data + 2); 00736 } else { 00737 snprintf(tmp, (int)sizeof(tmp), "Expected at least two byte hint, but was %d long\n", len); 00738 errorf(tmp); 00739 } 00740 break; 00741 case DUNDI_IE_DEPARTMENT: 00742 ies->q_dept = (char *)data + 2; 00743 break; 00744 case DUNDI_IE_ORGANIZATION: 00745 ies->q_org = (char *)data + 2; 00746 break; 00747 case DUNDI_IE_LOCALITY: 00748 ies->q_locality = (char *)data + 2; 00749 break; 00750 case DUNDI_IE_STATE_PROV: 00751 ies->q_stateprov = (char *)data + 2; 00752 break; 00753 case DUNDI_IE_COUNTRY: 00754 ies->q_country = (char *)data + 2; 00755 break; 00756 case DUNDI_IE_EMAIL: 00757 ies->q_email = (char *)data + 2; 00758 break; 00759 case DUNDI_IE_PHONE: 00760 ies->q_phone = (char *)data + 2; 00761 break; 00762 case DUNDI_IE_IPADDR: 00763 ies->q_ipaddr = (char *)data + 2; 00764 break; 00765 case DUNDI_IE_ENCDATA: 00766 /* Recalculate len as the remainder of the message, regardless of 00767 theoretical length */ 00768 len = datalen - 2; 00769 if ((len > 16) && !(len % 16)) { 00770 ies->encblock = (struct dundi_encblock *)(data + 2); 00771 ies->enclen = len - 16; 00772 } else { 00773 snprintf(tmp, (int)sizeof(tmp), "Invalid encrypted data length %d\n", len); 00774 errorf(tmp); 00775 } 00776 break; 00777 case DUNDI_IE_SHAREDKEY: 00778 if (len == 128) { 00779 ies->encsharedkey = (unsigned char *)(data + 2); 00780 } else { 00781 snprintf(tmp, (int)sizeof(tmp), "Invalid encrypted shared key length %d\n", len); 00782 errorf(tmp); 00783 } 00784 break; 00785 case DUNDI_IE_SIGNATURE: 00786 if (len == 128) { 00787 ies->encsig = (unsigned char *)(data + 2); 00788 } else { 00789 snprintf(tmp, (int)sizeof(tmp), "Invalid encrypted signature length %d\n", len); 00790 errorf(tmp); 00791 } 00792 break; 00793 case DUNDI_IE_CACHEBYPASS: 00794 ies->cbypass = 1; 00795 break; 00796 default: 00797 snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", dundi_ie2str(ie), ie, len); 00798 outputf(tmp); 00799 } 00800 /* Overwrite information element with 0, to null terminate previous portion */ 00801 data[0] = 0; 00802 datalen -= (len + 2); 00803 data += (len + 2); 00804 } 00805 /* Null-terminate last field */ 00806 *data = '\0'; 00807 if (datalen) { 00808 errorf("Invalid information element contents, strange boundary\n"); 00809 return -1; 00810 } 00811 return 0; 00812 }
void dundi_set_error | ( | void(*)(const char *) | func | ) |
Definition at line 630 of file dundi-parser.c.
References errorf.
Referenced by load_module().
00631 { 00632 errorf = func; 00633 }
void dundi_set_output | ( | void(*)(const char *) | func | ) |
Definition at line 625 of file dundi-parser.c.
References outputf.
Referenced by load_module().
00626 { 00627 outputf = func; 00628 }
void dundi_showframe | ( | struct dundi_hdr * | fhi, | |
int | rx, | |||
struct sockaddr_in * | sin, | |||
int | datalen | |||
) |
Definition at line 429 of file dundi-parser.c.
References ast_inet_ntoa(), dundi_hdr::cmdflags, dundi_hdr::cmdresp, commands, dundi_hdr::dtrans, dump_ies(), DUNDI_FLAG_RESERVED, DUNDI_FLAG_RETRANS, dundi_hdr::ies, dundi_hdr::iseqno, dundi_hdr::oseqno, outputf, and dundi_hdr::strans.
Referenced by dundi_send(), dundi_xmit(), and socket_read().
00430 { 00431 char *pref[] = { 00432 "Tx", 00433 "Rx", 00434 " ETx", 00435 " Erx" }; 00436 char *commands[] = { 00437 "ACK ", 00438 "DPDISCOVER ", 00439 "DPRESPONSE ", 00440 "EIDQUERY ", 00441 "EIDRESPONSE ", 00442 "PRECACHERQ ", 00443 "PRECACHERP ", 00444 "INVALID ", 00445 "UNKNOWN CMD ", 00446 "NULL ", 00447 "REQREQ ", 00448 "REGRESPONSE ", 00449 "CANCEL ", 00450 "ENCRYPT ", 00451 "ENCREJ " }; 00452 char class2[20]; 00453 char *class; 00454 char subclass2[20]; 00455 char *subclass; 00456 char tmp[256]; 00457 char retries[20]; 00458 if (ntohs(fhi->dtrans) & DUNDI_FLAG_RETRANS) 00459 strcpy(retries, "Yes"); 00460 else 00461 strcpy(retries, "No"); 00462 if ((ntohs(fhi->strans) & DUNDI_FLAG_RESERVED)) { 00463 /* Ignore frames with high bit set to 1 */ 00464 return; 00465 } 00466 if ((fhi->cmdresp & 0x3f) > (int)sizeof(commands)/(int)sizeof(char *)) { 00467 snprintf(class2, (int)sizeof(class2), "(%d?)", fhi->cmdresp); 00468 class = class2; 00469 } else { 00470 class = commands[(int)(fhi->cmdresp & 0x3f)]; 00471 } 00472 snprintf(subclass2, (int)sizeof(subclass2), "%02x", fhi->cmdflags); 00473 subclass = subclass2; 00474 snprintf(tmp, (int)sizeof(tmp), 00475 "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s (%s)\n", 00476 pref[rx], 00477 retries, fhi->oseqno, fhi->iseqno, class, fhi->cmdresp & 0x40 ? "Response" : "Command"); 00478 outputf(tmp); 00479 snprintf(tmp, (int)sizeof(tmp), 00480 "%s Flags: %s STrans: %5.5d DTrans: %5.5d [%s:%d]%s\n", (rx > 1) ? " " : "", 00481 subclass, ntohs(fhi->strans) & ~DUNDI_FLAG_RESERVED, ntohs(fhi->dtrans) & ~DUNDI_FLAG_RETRANS, 00482 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), 00483 fhi->cmdresp & 0x80 ? " (Final)" : ""); 00484 outputf(tmp); 00485 dump_ies(fhi->ies, rx > 1, datalen); 00486 }
int dundi_str_short_to_eid | ( | dundi_eid * | eid, | |
const char * | s | |||
) |
Definition at line 67 of file dundi-parser.c.
References ast_eid::eid.
Referenced by cache_lookup_internal().
00068 { 00069 unsigned int eid_int[6]; 00070 int x; 00071 if (sscanf(s, "%2x%2x%2x%2x%2x%2x", &eid_int[0], &eid_int[1], &eid_int[2], 00072 &eid_int[3], &eid_int[4], &eid_int[5]) != 6) 00073 return -1; 00074 for (x = 0; x < 6; x++) 00075 eid->eid[x] = eid_int[x]; 00076 return 0; 00077 }
static void internalerror | ( | const char * | str | ) | [static] |
Definition at line 43 of file dundi-parser.c.
00044 { 00045 fprintf(stderr, "WARNING: %s", str); 00046 }
static void internaloutput | ( | const char * | str | ) | [static] |
static char* proto2str | ( | int | proto, | |
char * | buf, | |||
int | bufsiz | |||
) | [static] |
Definition at line 221 of file dundi-parser.c.
References DUNDI_PROTO_H323, DUNDI_PROTO_IAX, DUNDI_PROTO_NONE, and DUNDI_PROTO_SIP.
Referenced by dump_answer().
00222 { 00223 switch(proto) { 00224 case DUNDI_PROTO_NONE: 00225 strncpy(buf, "None", bufsiz - 1); 00226 break; 00227 case DUNDI_PROTO_IAX: 00228 strncpy(buf, "IAX", bufsiz - 1); 00229 break; 00230 case DUNDI_PROTO_SIP: 00231 strncpy(buf, "SIP", bufsiz - 1); 00232 break; 00233 case DUNDI_PROTO_H323: 00234 strncpy(buf, "H.323", bufsiz - 1); 00235 break; 00236 default: 00237 snprintf(buf, bufsiz, "Unknown Proto(%d)", proto); 00238 } 00239 buf[bufsiz-1] = '\0'; 00240 return buf; 00241 }
Definition at line 49 of file dundi-parser.c.
Definition at line 48 of file dundi-parser.c.