#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 |
Definition in file dundi-parser.c.
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 }
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.
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] |
static void internaloutput | ( | const char * | str | ) | [static] |
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 }
void(*) errorf(const char *str) = internalerror [static] |
Definition at line 55 of file dundi-parser.c.
void(*) outputf(const char *str) = internaloutput [static] |
Definition at line 54 of file dundi-parser.c.