|
@@ -11,6 +11,8 @@
|
|
|
#include <netdb.h>
|
|
|
#include <arpa/nameser.h>
|
|
|
|
|
|
+#include "ip_addr.h"
|
|
|
+
|
|
|
|
|
|
#define MAX_QUERY_SIZE 8192
|
|
|
#define ANS_SIZE 8192
|
|
@@ -66,28 +68,9 @@ struct rdata* get_record(char* name, int type);
|
|
|
void free_rdata_list(struct rdata* head);
|
|
|
|
|
|
|
|
|
-/* gethostbyname wrappers
|
|
|
- * use this, someday htey will use a local cache */
|
|
|
-
|
|
|
-static inline struct hostent* resolvehost(const char* name)
|
|
|
-{
|
|
|
- struct hostent* he;
|
|
|
-
|
|
|
-#ifdef DNS_IP_HACK
|
|
|
-#endif
|
|
|
-
|
|
|
- he=gethostbyname(name); /*ipv4*/
|
|
|
|
|
|
-#ifdef USE_IPV6
|
|
|
- if(he==0){
|
|
|
- /*try ipv6*/
|
|
|
- he=gethostbyname2(name, AF_INET6);
|
|
|
- }
|
|
|
-#endif
|
|
|
- return he;
|
|
|
-}
|
|
|
|
|
|
-struct hostent* sip_resolvehost(char* name, unsigned short* port);
|
|
|
+#define rev_resolvehost(ip) gethostbyaddr((ip)->u.addr, (ip)->len, (ip)->af);
|
|
|
|
|
|
|
|
|
|
|
@@ -97,16 +80,53 @@ struct hostent* sip_resolvehost(char* name, unsigned short* port);
|
|
|
(((c)>='a') && ((c)<='f'))? ((c)-'a')+10 : -1 )
|
|
|
|
|
|
|
|
|
-#define rev_resolvehost(ip) gethostbyaddr((ip)->u.addr, (ip)->len, (ip)->af);
|
|
|
|
|
|
|
|
|
|
|
|
-#if 0
|
|
|
-/* returns an ip_addr struct.; on error retunrs 0 and sets err (if !=0)
|
|
|
- * the ip_addr struct is static, so subsequent calls will destroy its
|
|
|
- * content */
|
|
|
-static /*inline*/ struct ip_addr* str2ip6(unsigned char* str, unsigned int len,
|
|
|
- int* err)
|
|
|
+/* converts a str to an ipv4 address, returns the address or 0 on error
|
|
|
+ Warning: the result is a pointer to a statically allocated structure */
|
|
|
+static inline struct ip_addr* str2ip(unsigned char* str, unsigned int len)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ unsigned char *limit;
|
|
|
+ unsigned char *init;
|
|
|
+ static struct ip_addr ip;
|
|
|
+
|
|
|
+ /*init*/
|
|
|
+ ip.u.addr32[0]=0;
|
|
|
+ i=0;
|
|
|
+ limit=str+len;
|
|
|
+ init=str;
|
|
|
+
|
|
|
+ for(;str<limit ;str++){
|
|
|
+ if (*str=='.'){
|
|
|
+ i++;
|
|
|
+ if (i>3) goto error_dots;
|
|
|
+ }else if ( (*str <= '9' ) && (*str >= '0') ){
|
|
|
+ ip.u.addr[i]=ip.u.addr[i]*10+*str-'0';
|
|
|
+ }else{
|
|
|
+ //error unknown char
|
|
|
+ goto error_char;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ip.af=AF_INET;
|
|
|
+ ip.len=4;
|
|
|
+
|
|
|
+ return &ip;
|
|
|
+
|
|
|
+error_dots:
|
|
|
+ DBG("str2ip: ERROR: too many dots in [%.*s]\n", (int)len, init);
|
|
|
+ return 0;
|
|
|
+error_char:
|
|
|
+ DBG("str2ip: WARNING: unexpected char %c in %.*s\n", *str,(int)len, init);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+/* returns an ip_addr struct.; on error returns 0
|
|
|
+ * the ip_addr struct is static, so subsequent calls will destroy its content*/
|
|
|
+static inline struct ip_addr* str2ip6(unsigned char* str, unsigned int len)
|
|
|
{
|
|
|
int i, idx1, rest;
|
|
|
int no_colons;
|
|
@@ -143,6 +163,7 @@ static /*inline*/ struct ip_addr* str2ip6(unsigned char* str, unsigned int len,
|
|
|
addr=addr_end;
|
|
|
}else{
|
|
|
double_colon=1;
|
|
|
+ addr[i]=htons(addr[i]);
|
|
|
i++;
|
|
|
}
|
|
|
}else if ((hex=HEX2I(*str))>=0){
|
|
@@ -153,29 +174,70 @@ static /*inline*/ struct ip_addr* str2ip6(unsigned char* str, unsigned int len,
|
|
|
goto error_char;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+ if (no_colons<2) goto error_too_few_colons;
|
|
|
+ if (!double_colon){ /* not ending in ':' */
|
|
|
+ addr[i]=htons(addr[i]);
|
|
|
+ i++;
|
|
|
+ }
|
|
|
rest=8-i-idx1;
|
|
|
memcpy(addr_start+idx1+rest, addr_end, i*sizeof(unsigned short));
|
|
|
- if (err) *err=0;
|
|
|
return &ip;
|
|
|
|
|
|
error_too_many_colons:
|
|
|
DBG("str2ip6: ERROR: too many colons in [%.*s]\n", (int) len, init);
|
|
|
- if (err) *err=1;
|
|
|
+ return 0;
|
|
|
+
|
|
|
+error_too_few_colons:
|
|
|
+ DBG("str2ip6: ERROR: too few colons in [%.*s]\n", (int) len, init);
|
|
|
return 0;
|
|
|
|
|
|
error_colons:
|
|
|
DBG("str2ip6: ERROR: too many double colons in [%.*s]\n", (int) len, init);
|
|
|
- if (err) *err=1;
|
|
|
return 0;
|
|
|
|
|
|
error_char:
|
|
|
DBG("str2ip6: WARNING: unexpected char %c in [%.*s]\n", *str, (int) len,
|
|
|
init);
|
|
|
- if (err) *err=1;
|
|
|
return 0;
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+struct hostent* sip_resolvehost(char* name, unsigned short* port);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+/* gethostbyname wrappers
|
|
|
+ * use this, someday they will use a local cache */
|
|
|
+
|
|
|
+static inline struct hostent* resolvehost(const char* name)
|
|
|
+{
|
|
|
+ struct hostent* he;
|
|
|
+#ifdef DNS_IP_HACK
|
|
|
+ struct ip_addr* ip;
|
|
|
+ int len;
|
|
|
+
|
|
|
+ len=strlen(name);
|
|
|
+ /* check if it's an ip address */
|
|
|
+ if ( ((ip=str2ip(name, len))!=0)
|
|
|
+#ifdef USE_IPV6
|
|
|
+ || ((ip=str2ip6(name, len))!=0)
|
|
|
+#endif
|
|
|
+ ){
|
|
|
+ /* we are lucky, this is an ip address */
|
|
|
+ return ip_addr2he(name, len, ip);
|
|
|
+ }
|
|
|
+
|
|
|
#endif
|
|
|
+ he=gethostbyname(name); /*ipv4*/
|
|
|
+#ifdef USE_IPV6
|
|
|
+ if(he==0){
|
|
|
+ /*try ipv6*/
|
|
|
+ he=gethostbyname2(name, AF_INET6);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ return he;
|
|
|
+}
|
|
|
|
|
|
|
|
|
|