Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

srv.c

Go to the documentation of this file.
00001 /* 00002 * ENUM Support for Asterisk 00003 * 00004 * Copyright (C) 2003 Digium 00005 * 00006 * Written by Mark Spencer <markster@digium.com> 00007 * 00008 * Funding provided by nic.at 00009 * 00010 * Distributed under the terms of the GNU GPL 00011 * 00012 */ 00013 00014 #include <sys/types.h> 00015 #include <netinet/in.h> 00016 #include <arpa/nameser.h> 00017 #if __APPLE_CC__ >= 1495 00018 #include <arpa/nameser_compat.h> 00019 #endif 00020 #include <resolv.h> 00021 #include <stdio.h> 00022 #include <string.h> 00023 #include <unistd.h> 00024 00025 #include <asterisk/channel.h> 00026 #include <asterisk/logger.h> 00027 #include <asterisk/srv.h> 00028 #include <asterisk/dns.h> 00029 #include <asterisk/options.h> 00030 #include <asterisk/utils.h> 00031 00032 #ifdef __APPLE__ 00033 #undef T_SRV 00034 #define T_SRV 33 00035 #endif 00036 00037 struct srv { 00038 unsigned short priority; 00039 unsigned short weight; 00040 unsigned short portnum; 00041 } __attribute__ ((__packed__)); 00042 00043 static int parse_srv(unsigned char *host, int hostlen, int *portno, unsigned char *answer, int len, unsigned char *msg) 00044 { 00045 int res = 0; 00046 struct srv *srv = (struct srv *)answer; 00047 char repl[256] = ""; 00048 00049 if (len < sizeof(struct srv)) { 00050 printf("Length too short\n"); 00051 return -1; 00052 } 00053 answer += sizeof(struct srv); 00054 len -= sizeof(struct srv); 00055 00056 if ((res = dn_expand(msg,answer + len,answer, repl, sizeof(repl) - 1)) < 0) { 00057 ast_log(LOG_WARNING, "Failed to expand hostname\n"); 00058 return -1; 00059 } 00060 if (res && strcmp(repl, ".")) { 00061 ast_verbose( VERBOSE_PREFIX_3 "parse_srv: SRV mapped to host %s, port %d\n", repl, ntohs(srv->portnum)); 00062 if (host) { 00063 strncpy(host, repl, hostlen - 2); 00064 host[hostlen-1] = '\0'; 00065 } 00066 if (portno) 00067 *portno = ntohs(srv->portnum); 00068 return(0); 00069 } 00070 return(-1); 00071 } 00072 00073 struct srv_context { 00074 char *host; 00075 int hostlen; 00076 int *port; 00077 }; 00078 00079 static int srv_callback(void *context, u_char *answer, int len, u_char *fullanswer) 00080 { 00081 struct srv_context *c = (struct srv_context *)context; 00082 00083 if (parse_srv(c->host, c->hostlen, c->port, answer, len, fullanswer)) { 00084 ast_log(LOG_WARNING, "Failed to parse srv\n"); 00085 return -1; 00086 } 00087 00088 if (!ast_strlen_zero(c->host)) 00089 return 1; 00090 00091 return 0; 00092 } 00093 00094 int ast_get_srv(struct ast_channel *chan, char *host, int hostlen, int *port, const char *service) 00095 { 00096 struct srv_context context; 00097 int ret; 00098 00099 context.host = host; 00100 context.hostlen = hostlen; 00101 context.port = port; 00102 00103 if (chan && ast_autoservice_start(chan) < 0) 00104 return -1; 00105 00106 ret = ast_search_dns(&context, service, C_IN, T_SRV, srv_callback); 00107 00108 if (chan) 00109 ret |= ast_autoservice_stop(chan); 00110 00111 if (ret <= 0) { 00112 strcpy(host, ""); 00113 *port = -1; 00114 return ret; 00115 } 00116 return ret; 00117 }

Generated on Sat Jun 12 16:40:59 2004 for Asterisk by doxygen 1.3.7