[PATCH] core: resolve.h For IPv6 use inet_pton instead of custom parsing functions

Marius Zbihlei marius.zbihlei at 1and1.ro
Thu Dec 15 17:39:23 CET 2011


---
 resolve.h |  117 ++++++++++++++----------------------------------------------
 1 files changed, 28 insertions(+), 89 deletions(-)

diff --git a/resolve.h b/resolve.h
index 5611c9d..08b524b 100644
--- a/resolve.h
+++ b/resolve.h
@@ -274,111 +274,50 @@ error_dots:
 
 
 #ifdef USE_IPV6
+#include <arpa/inet.h> /*for inet_pton*/
+
 /* 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(str* st)
-{
-	int i, idx1, rest;
-	int no_colons;
-	int double_colon;
-	int hex;
+ 
+static inline struct ip_addr* str2ip6(str* st){
 	static struct ip_addr ip;
-	unsigned short* addr_start;
-	unsigned short addr_end[8];
-	unsigned short* addr;
-	unsigned char* limit;
-	unsigned char* s;
+	char addr[128];
+	unsigned char* buf = ip.u.addr;
+#ifdef RESOLVE_DBG
+	unsigned short* addr_start = ip.u.addr16;
+#endif
+	memset(addr, 0, sizeof(addr));
+
+	if(!st || !st->s || !st->len) goto error;
 	
-	/* init */
-	if ((st->len) && (st->s[0]=='[')){
-		/* skip over [ ] */
-		if (st->s[st->len-1]!=']') goto error_char;
-		s=(unsigned char*)(st->s+1);
-		limit=(unsigned char*)(st->s+st->len-1);
-	}else{
-		s=(unsigned char*)st->s;
-		limit=(unsigned char*)(st->s+st->len);
-	}
-	i=idx1=rest=0;
-	double_colon=0;
-	no_colons=0;
 	ip.af=AF_INET6;
 	ip.len=16;
-	addr_start=ip.u.addr16;
-	addr=addr_start;
-	memset(addr_start, 0 , 8*sizeof(unsigned short));
-	memset(addr_end, 0 , 8*sizeof(unsigned short));
-	for (; s<limit; s++){
-		if (*s==':'){
-			no_colons++;
-			if (no_colons>7) goto error_too_many_colons;
-			if (double_colon){
-				idx1=i;
-				i=0;
-				if (addr==addr_end) goto error_colons;
-				addr=addr_end;
-			}else{
-				double_colon=1;
-				addr[i]=htons(addr[i]);
-				i++;
-			}
-		}else if ((hex=HEX2I(*s))>=0){
-				addr[i]=addr[i]*16+hex;
-				double_colon=0;
-		}else{
-			/* error, unknown char */
-			goto error_char;
-		}
-	}
-	if (!double_colon){ /* not ending in ':' */
-		addr[i]=htons(addr[i]);
-		i++; 
-	}
-	/* if address contained '::' fix it */
-	if (addr==addr_end){
-		rest=8-i-idx1;
-		memcpy(addr_start+idx1+rest, addr_end, i*sizeof(unsigned short));
-	}else{
-		/* no double colons inside */
-		if (no_colons<7) goto error_too_few_colons;
+
+	if ((st->s[0]=='[')){
+		/* skip over [ ] */
+		if (st->s[st->len-1]!=']') goto error;
+		memcpy(addr, st->s+1, st->len-2);
+	} else {
+		memcpy(addr, st->s, st->len);
 	}
-/*
-	DBG("str2ip6: idx1=%d, rest=%d, no_colons=%d, hex=%x\n",
-			idx1, rest, no_colons, hex);
-	DBG("str2ip6: address %x:%x:%x:%x:%x:%x:%x:%x\n", 
-			addr_start[0], addr_start[1], addr_start[2],
-			addr_start[3], addr_start[4], addr_start[5],
-			addr_start[6], addr_start[7] );
-*/
-	return &ip;
 
-error_too_many_colons:
-#ifdef RESOLVE_DBG
-	DBG("str2ip6: ERROR: too many colons in [%.*s]\n", st->len, st->s);
-#endif
-	return 0;
+	if( inet_pton(AF_INET6, addr, buf) != 1) goto error;
 
-error_too_few_colons:
 #ifdef RESOLVE_DBG
-	DBG("str2ip6: ERROR: too few colons in [%.*s]\n", st->len, st->s);
+	  DBG("str2ip6: address %x:%x:%x:%x:%x:%x:%x:%x\n",
+			addr_start[0], addr_start[1], addr_start[2],
+			addr_start[3], addr_start[4], addr_start[5],
+			addr_start[6], addr_start[7] );
 #endif
-	return 0;
+	return &ip;
 
-error_colons:
+error:
 #ifdef RESOLVE_DBG
-	DBG("str2ip6: ERROR: too many double colons in [%.*s]\n", st->len, st->s);
+	DBG("str2ip6: ERROR: could not resolve address [%.*s]\n", st->len, st->s);
 #endif
 	return 0;
-
-error_char:
-	/*
-	DBG("str2ip6: WARNING: unexpected char %c in  [%.*s]\n", *s, st->len,
-			st->s);*/
-	return 0;
 }
-#endif /* USE_IPV6 */
-
-
+#endif /*USE_IPV6*/
 
 struct hostent* _sip_resolvehost(str* name, unsigned short* port, char* proto);
 
-- 
1.7.0


--------------020900090602030505080308--



More information about the sr-users mailing list