31 #include <sys/socket.h> 32 #include <netinet/in.h> 33 #include <arpa/inet.h> 48 fprintf(stderr,
"WARNING: %s", str);
59 if (s && (maxlen > 0))
63 sprintf(s,
"%02hhX", (
unsigned char)eid->
eid[x]);
72 unsigned int eid_int[6];
74 if (sscanf(s,
"%2x%2x%2x%2x%2x%2x", &eid_int[0], &eid_int[1], &eid_int[2],
75 &eid_int[3], &eid_int[4], &eid_int[5]) != 6)
77 for (x = 0; x < 6; x++)
78 eid->
eid[x] = eid_int[x];
86 if (eid->
eid[x])
return 0;
95 snprintf(output, maxlen,
"%s", (
char *) value);
100 snprintf(output, maxlen,
"Bypass Caches");
108 snprintf(output, maxlen,
"Invalid EID len %d", len);
114 buf[bufsiz-1] =
'\0';
116 strncat(buf,
"TTLEXPIRED|", bufsiz - strlen(buf) - 1);
119 strncat(buf,
"DONTASK|", bufsiz - strlen(buf) - 1);
122 strncat(buf,
"UNAFFECTED|", bufsiz - strlen(buf) - 1);
126 strcpy(buf,
"NONE|");
127 buf[strlen(buf)-1] =
'\0';
137 if (len <
sizeof(*hint)) {
138 snprintf(output, maxlen,
"<invalid contents>");
145 if (datalen >
sizeof(tmp3) - 1)
146 datalen =
sizeof(tmp3) - 1;
148 memcpy(tmp3, hint->
data, datalen);
149 tmp3[datalen] =
'\0';
154 snprintf(output, maxlen,
"[%s]", tmp2);
156 snprintf(output, maxlen,
"[%s] %s", tmp2, tmp3);
161 static const char *
const causes[] = {
172 if (len <
sizeof(*cause)) {
173 snprintf(output, maxlen,
"<invalid contents>");
181 if (datalen >
sizeof(tmp2) - 1)
182 datalen =
sizeof(tmp2) - 1;
184 memcpy(tmp2, cause->
desc, datalen);
185 tmp2[datalen] =
'\0';
189 snprintf(output, maxlen,
"%s", causes[causecode]);
191 snprintf(output, maxlen,
"%s: %s", causes[causecode], tmp2);
194 snprintf(output, maxlen,
"%d", causecode);
196 snprintf(output, maxlen,
"%d: %s", causecode, tmp2);
202 if (len == (
int)
sizeof(
unsigned int))
203 snprintf(output, maxlen,
"%lu", (
unsigned long)ntohl(*((
unsigned int *)value)));
210 if (len == (
int)
sizeof(
unsigned short))
211 snprintf(output, maxlen,
"%d", ntohs(*((
unsigned short *)value)));
218 if (len == (
int)
sizeof(
unsigned char))
219 snprintf(output, maxlen,
"%d", *((
unsigned char *)value));
228 strncpy(buf,
"None", bufsiz - 1);
231 strncpy(buf,
"IAX", bufsiz - 1);
234 strncpy(buf,
"SIP", bufsiz - 1);
237 strncpy(buf,
"H.323", bufsiz - 1);
240 snprintf(buf, bufsiz,
"Unknown Proto(%d)", proto);
242 buf[bufsiz-1] =
'\0';
249 buf[bufsiz-1] =
'\0';
251 strncat(buf,
"EXISTS|", bufsiz - strlen(buf) - 1);
254 strncat(buf,
"MATCHMORE|", bufsiz - strlen(buf) - 1);
257 strncat(buf,
"CANMATCH|", bufsiz - strlen(buf) - 1);
260 strncat(buf,
"IGNOREPAT|", bufsiz - strlen(buf) - 1);
263 strncat(buf,
"RESIDENCE|", bufsiz - strlen(buf) - 1);
266 strncat(buf,
"COMMERCIAL|", bufsiz - strlen(buf) - 1);
269 strncat(buf,
"MOBILE", bufsiz - strlen(buf) - 1);
272 strncat(buf,
"NOUNSLCTD|", bufsiz - strlen(buf) - 1);
275 strncat(buf,
"NOCOMUNSLTD|", bufsiz - strlen(buf) - 1);
279 strcpy(buf,
"NONE|");
280 buf[strlen(buf)-1] =
'\0';
293 if (len <
sizeof(*answer)) {
294 snprintf(output, maxlen,
"Invalid Answer");
301 if (datalen >
sizeof(tmp) - 1)
302 datalen =
sizeof(
tmp) - 1;
304 memcpy(tmp, answer->
data, datalen);
308 snprintf(output, maxlen,
"[%s] %d <%s/%s> from [%s]",
319 if ((len > 16) && !(len % 16)) {
322 snprintf(iv + (x << 1), 3,
"%02hhx", ((
unsigned char *)value)[x]);
324 snprintf(output, maxlen,
"[IV %s] %d encrypted blocks\n", iv, len / 16);
326 snprintf(output, maxlen,
"Invalid Encrypted Datalen %d", len);
332 unsigned char *u =
value;
333 output[maxlen - 1] =
'\0';
334 strcpy(output,
"[ ");
335 for (x=0;x<
len;x++) {
336 snprintf(output + strlen(output), maxlen - strlen(output) - 1,
"%02hhx ", u[x]);
338 strncat(output + strlen(output),
"]", maxlen - strlen(output) - 1);
399 if (ielen + 2> len) {
400 snprintf(tmp, (
int)
sizeof(tmp),
"Total IE length of %d bytes exceeds remaining frame length of %d bytes\n", ielen + 2, len);
408 infoelts[x].
dump(interp, (
int)
sizeof(interp), iedata + 2, ielen);
409 snprintf(tmp, (
int)
sizeof(tmp),
" %s%-15.15s : %s\n", (spaces ?
" " :
"" ),
infoelts[x].
name, interp);
413 snprintf(interp, (
int)
sizeof(interp),
"%d bytes", ielen);
415 strcpy(interp,
"Present");
416 snprintf(tmp, (
int)
sizeof(tmp),
" %s%-15.15s : %s\n", (spaces ?
" " :
"" ),
infoelts[x].
name, interp);
423 snprintf(tmp, (
int)
sizeof(tmp),
" %sUnknown IE %03d : Present\n", (spaces ?
" " :
"" ), ie);
426 iedata += (2 + ielen);
461 snprintf(class2,
sizeof(class2),
"(%d?)", fhi->
cmdresp & 0x3f);
464 class = commands[fhi->cmdresp & 0x3f];
466 snprintf(subclass2,
sizeof(subclass2),
"%02hhx", (
unsigned char)fhi->
cmdflags);
467 subclass = subclass2;
468 snprintf(tmp,
sizeof(tmp),
469 "%s-Frame -- OSeqno: %3.3d ISeqno: %3.3d Type: %s (%s)\n",
474 snprintf(tmp, (
int)
sizeof(tmp),
475 "%s Flags: %s STrans: %5.5d DTrans: %5.5d [%s]%s\n", (rx > 1) ?
" " :
"",
478 fhi->
cmdresp & 0x80 ?
" (Final)" :
"");
487 if (datalen > ((
int)
sizeof(ied->
buf) - ied->
pos)) {
488 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);
493 ied->
buf[ied->
pos++] = datalen;
494 memcpy(ied->
buf + ied->
pos, data, datalen);
502 int datalen = data ? strlen(data) + 1 : 1;
503 if (datalen > ((
int)
sizeof(ied->
buf) - ied->
pos)) {
504 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);
509 ied->
buf[ied->
pos++] = datalen;
510 ied->
buf[ied->
pos++] = cause;
512 memcpy(ied->
buf + ied->
pos, data, datalen-1);
513 ied->
pos += datalen-1;
521 int datalen = data ? strlen(data) + 2 : 2;
522 if (datalen > ((
int)
sizeof(ied->
buf) - ied->
pos)) {
523 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);
528 ied->
buf[ied->
pos++] = datalen;
529 flags = htons(flags);
530 memcpy(ied->
buf + ied->
pos, &flags,
sizeof(flags));
533 memcpy(ied->
buf + ied->
pos, data, datalen-2);
534 ied->
pos += datalen-2;
543 if (datalen > ((
int)
sizeof(ied->
buf) - ied->
pos)) {
544 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);
549 ied->
buf[ied->
pos++] = datalen;
550 memcpy(ied->
buf + ied->
pos, iv, 16);
553 memcpy(ied->
buf + ied->
pos, data, datalen-16);
554 ied->
pos += datalen-16;
562 int datalen = data ? strlen(data) + 11 : 11;
565 if (datalen > ((
int)
sizeof(ied->
buf) - ied->
pos)) {
566 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);
571 ied->
buf[ied->
pos++] = datalen;
574 ied->
buf[ied->
pos++] = protocol;
576 memcpy(ied->
buf + ied->
pos, &myw, 2);
579 memcpy(ied->
buf + ied->
pos, &myw, 2);
581 memcpy(ied->
buf + ied->
pos, data, datalen-11);
582 ied->
pos += datalen-11;
594 newval = htonl(value);
600 unsigned short newval;
601 newval = htons(value);
641 memset(ies, 0, (
int)
sizeof(
struct dundi_ies));
646 while(datalen >= 2) {
649 if (len > datalen - 2) {
650 errorf(
"Information element length exceeds message size\n");
657 errorf(
"Improper entity identifer, expecting 6 bytes!\n");
663 errorf(
"Too many entities in stack!\n");
667 errorf(
"Improper requested entity identifer, expecting 6 bytes!\n");
679 snprintf(tmp, (
int)
sizeof(tmp),
"Answer expected to be >=%d bytes long but was %d\n", (
int)
sizeof(
struct dundi_answer), len);
685 errorf(
"Ignoring extra answers!\n");
689 if (len != (
int)
sizeof(
unsigned short)) {
690 snprintf(tmp, (
int)
sizeof(tmp),
"Expecting ttl to be %d bytes long but was %d\n", (
int)
sizeof(
unsigned short), len);
693 ies->
ttl = ntohs(*((
unsigned short *)(data + 2)));
696 if (len != (
int)
sizeof(
unsigned short)) {
697 snprintf(tmp, (
int)
sizeof(tmp),
"Expecting version to be %d bytes long but was %d\n", (
int)
sizeof(
unsigned short), len);
700 ies->
version = ntohs(*((
unsigned short *)(data + 2)));
703 if (len != (
int)
sizeof(
unsigned short)) {
704 snprintf(tmp, (
int)
sizeof(tmp),
"Expecting expiration to be %d bytes long but was %d\n", (
int)
sizeof(
unsigned short), len);
707 ies->
expiration = ntohs(*((
unsigned short *)(data + 2)));
710 if (len != (
int)
sizeof(
unsigned int)) {
711 snprintf(tmp, (
int)
sizeof(tmp),
"Expecting expiration to be %d bytes long but was %d\n", (
int)
sizeof(
unsigned int), len);
714 ies->
keycrc32 = ntohl(*((
unsigned int *)(data + 2)));
720 snprintf(tmp, (
int)
sizeof(tmp),
"Expected single byte Unknown command, but was %d long\n", len);
726 ies->
cause = data[2];
729 snprintf(tmp, (
int)
sizeof(tmp),
"Expected at least one byte cause, but was %d long\n", len);
737 snprintf(tmp, (
int)
sizeof(tmp),
"Expected at least two byte hint, but was %d long\n", len);
742 ies->
q_dept = (
char *)data + 2;
745 ies->
q_org = (
char *)data + 2;
757 ies->
q_email = (
char *)data + 2;
760 ies->
q_phone = (
char *)data + 2;
769 if ((len > 16) && !(len % 16)) {
773 snprintf(tmp, (
int)
sizeof(tmp),
"Invalid encrypted data length %d\n", len);
781 snprintf(tmp, (
int)
sizeof(tmp),
"Invalid encrypted shared key length %d\n", len);
787 ies->
encsig = (
unsigned char *)(data + 2);
789 snprintf(tmp, (
int)
sizeof(tmp),
"Invalid encrypted signature length %d\n", len);
797 snprintf(tmp, (
int)
sizeof(tmp),
"Ignoring unknown information element '%s' (%d) of length %d\n",
dundi_ie2str(ie), ie, len);
802 datalen -= (len + 2);
808 errorf(
"Invalid information element contents, strange boundary\n");
static void internaloutput(const char *str)
#define DUNDI_IE_EXPIRATION
static void dump_hint(char *output, int maxlen, void *value, int len)
#define DUNDI_IE_EID_DIRECT
Asterisk main include file. File version handling, generic pbx functions.
Distributed Universal Number Discovery (DUNDi) See also.
int dundi_ie_append_eid(struct dundi_ie_data *ied, unsigned char ie, dundi_eid *eid)
#define DUNDI_IE_CACHEBYPASS
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Convert an EID to a string.
static void dump_eid(char *output, int maxlen, void *value, int len)
struct dundi_answer * answers[DUNDI_MAX_ANSWERS+1]
static void dump_answer(char *output, int maxlen, void *value, int len)
#define DUNDI_IE_SHAREDKEY
void dundi_set_error(void(*func)(const char *))
int dundi_ie_append_addr(struct dundi_ie_data *ied, unsigned char ie, struct sockaddr_in *sin)
char * dundi_eid_to_str_short(char *s, int maxlen, dundi_eid *eid)
#define DUNDI_FLAG_RETRANS
int eid_direct[DUNDI_MAX_STACK+1]
int dundi_ie_append_hint(struct dundi_ie_data *ied, unsigned char ie, unsigned short flags, char *data)
#define DUNDI_IE_DEPARTMENT
dundi_eid * eids[DUNDI_MAX_STACK+1]
#define DUNDI_FLAG_RESERVED
static void dump_raw(char *output, int maxlen, void *value, int len)
Socket address structure.
An Entity ID is essentially a MAC address, brief and unique.
int dundi_ie_append_raw(struct dundi_ie_data *ied, unsigned char ie, void *data, int datalen)
#define ast_strlen_zero(foo)
static struct dundi_ie infoelts[]
#define DUNDI_IE_LOCALITY
#define DUNDI_IE_KEYCRC32
#define DUNDI_IE_SIGNATURE
int dundi_ie_append_encdata(struct dundi_ie_data *ied, unsigned char ie, unsigned char *iv, void *data, int datalen)
int dundi_ie_append(struct dundi_ie_data *ied, unsigned char ie)
struct dundi_encblock * encblock
void dundi_set_output(void(*func)(const char *))
Asterisk internal frame definitions.
static void internalerror(const char *str)
static struct agi_command commands[]
AGI commands list.
static void dump_encrypted(char *output, int maxlen, void *value, int len)
static void dump_cause(char *output, int maxlen, void *value, int len)
static const struct causes_map causes[]
static void dump_byte(char *output, int maxlen, void *value, int len)
static int answer(void *data)
unsigned char * encsharedkey
#define DUNDI_MAX_ANSWERS
int dundi_ie_append_str(struct dundi_ie_data *ied, unsigned char ie, char *str)
int dundi_ie_append_cause(struct dundi_ie_data *ied, unsigned char ie, unsigned char cause, char *data)
static void dump_ies(unsigned char *iedata, int spaces, int len)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static void dump_short(char *output, int maxlen, void *value, int len)
#define DUNDI_IE_CALLED_CONTEXT
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
#define DUNDI_IE_ORGANIZATION
static void(* outputf)(const char *str)
int dundi_ie_append_short(struct dundi_ie_data *ied, unsigned char ie, unsigned short value)
void dundi_showframe(struct dundi_hdr *fhi, int rx, struct ast_sockaddr *sin, int datalen)
#define DUNDI_IE_CALLED_NUMBER
static char * proto2str(int proto, char *buf, int bufsiz)
static void dump_cbypass(char *output, int maxlen, void *value, int len)
#define DUNDI_IE_STATE_PROV
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
int dundi_eid_zero(dundi_eid *eid)
void(* dump)(char *output, int maxlen, void *value, int len)
int dundi_parse_ies(struct dundi_ies *ies, unsigned char *data, int datalen)
static void dump_int(char *output, int maxlen, void *value, int len)
int dundi_ie_append_byte(struct dundi_ie_data *ied, unsigned char ie, unsigned char dat)
int dundi_ie_append_int(struct dundi_ie_data *ied, unsigned char ie, unsigned int value)
static void(* errorf)(const char *str)
int dundi_str_short_to_eid(dundi_eid *eid, const char *s)
const char * dundi_ie2str(int ie)
char * dundi_flags2str(char *buf, int bufsiz, int flags)
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)
char * dundi_hint2str(char *buf, int bufsiz, int flags)
static void dump_string(char *output, int maxlen, void *value, int len)