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 if (option_verbose > 3) 00062 ast_verbose( VERBOSE_PREFIX_3 "parse_srv: SRV mapped to host %s, port %d\n", repl, ntohs(srv->portnum)); 00063 if (host) { 00064 strncpy(host, repl, hostlen - 1); 00065 host[hostlen-1] = '\0'; 00066 } 00067 if (portno) 00068 *portno = ntohs(srv->portnum); 00069 return(0); 00070 } 00071 return(-1); 00072 } 00073 00074 struct srv_context { 00075 char *host; 00076 int hostlen; 00077 int *port; 00078 }; 00079 00080 static int srv_callback(void *context, u_char *answer, int len, u_char *fullanswer) 00081 { 00082 struct srv_context *c = (struct srv_context *)context; 00083 00084 if (parse_srv(c->host, c->hostlen, c->port, answer, len, fullanswer)) { 00085 ast_log(LOG_WARNING, "Failed to parse srv\n"); 00086 return -1; 00087 } 00088 00089 if (!ast_strlen_zero(c->host)) 00090 return 1; 00091 00092 return 0; 00093 } 00094 00095 int ast_get_srv(struct ast_channel *chan, char *host, int hostlen, int *port, const char *service) 00096 { 00097 struct srv_context context; 00098 int ret; 00099 00100 context.host = host; 00101 context.hostlen = hostlen; 00102 context.port = port; 00103 00104 if (chan && ast_autoservice_start(chan) < 0) 00105 return -1; 00106 00107 ret = ast_search_dns(&context, service, C_IN, T_SRV, srv_callback); 00108 00109 if (chan) 00110 ret |= ast_autoservice_stop(chan); 00111 00112 if (ret <= 0) { 00113 host[0] = '\0'; 00114 *port = -1; 00115 return ret; 00116 } 00117 return ret; 00118 }

Generated on Fri Sep 24 21:03:48 2004 for Asterisk by doxygen 1.3.8