[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