Hello.
Please pull
git://git.skbuff.net/gitroot/yoshfuji/net-2.6.19-20060825-inet6
for the following updates on top of the net-2.6.19 tree.
Regards,
HEADLINES
---------
[IPV6] MIP6: Several obvious clean-ups.
[IPV6] ROUTE: Routing by Traffic Class.
[IPV6] ROUTE: Routing by FWMARK.
[NET]: Add common helper functions to convert IPv6/IPv4 address string to
network address structure.
[NETFILTER] NF_CONNTRACK_FTP: Use in6_pton() to convert address string.
DIFFSTAT
--------
include/linux/fib_rules.h | 2
include/linux/inet.h | 2
include/net/flow.h | 2
net/core/utils.c | 215 ++++++++++++++++++++++++++++++++++++++
net/ipv6/Kconfig | 7 +
net/ipv6/ah6.c | 45 +-------
net/ipv6/exthdrs.c | 1
net/ipv6/fib6_rules.c | 26 +++++
net/ipv6/mip6.c | 6 +
net/ipv6/route.c | 1
net/netfilter/nf_conntrack_ftp.c | 96 +----------------
11 files changed, 268 insertions(+), 135 deletions(-)
CHANGESETS
----------
commit 6dabb77fd82cd927727d5fb8136eff2e123910f5
Author: YOSHIFUJI Hideaki <[EMAIL PROTECTED]>
Date: Thu Aug 24 23:18:12 2006 +0900
[IPV6] MIP6: Several obvious clean-ups.
- Remove redundant code. Pointed out by Brian Haley <[EMAIL PROTECTED]>.
- Unify code paths with/without CONFIG_IPV6_MIP.
- Use NIP6_FMT for IPv6 address textual presentation.
- Fold long line. Pointed out by David Miller <[EMAIL PROTECTED]>.
Signed-off-by: YOSHIFUJI Hideaki <[EMAIL PROTECTED]>
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 164546b..9b007eb 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -128,9 +128,7 @@ static void ipv6_rearrange_destopt(struc
off += optlen;
len -= optlen;
}
- if (len == 0)
- return;
-
+ /* Note: ok if len == 0 */
bad:
return;
}
@@ -175,11 +173,7 @@ static void ipv6_rearrange_rthdr(struct
ipv6_addr_copy(&iph->daddr, &final_addr);
}
-#ifdef CONFIG_IPV6_MIP6
static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len, int dir)
-#else
-static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len)
-#endif
{
union {
struct ipv6hdr *iph;
@@ -194,30 +188,12 @@ #endif
while (exthdr.raw < end) {
switch (nexthdr) {
-#ifdef CONFIG_IPV6_MIP6
- case NEXTHDR_HOP:
- if (!zero_out_mutable_opts(exthdr.opth)) {
- LIMIT_NETDEBUG(
- KERN_WARNING "overrun %sopts\n",
- nexthdr == NEXTHDR_HOP ?
- "hop" : "dest");
- return -EINVAL;
- }
- break;
case NEXTHDR_DEST:
+#ifdef CONFIG_IPV6_MIP6
if (dir == XFRM_POLICY_OUT)
ipv6_rearrange_destopt(iph, exthdr.opth);
- if (!zero_out_mutable_opts(exthdr.opth)) {
- LIMIT_NETDEBUG(
- KERN_WARNING "overrun %sopts\n",
- nexthdr == NEXTHDR_HOP ?
- "hop" : "dest");
- return -EINVAL;
- }
- break;
-#else
+#endif
case NEXTHDR_HOP:
- case NEXTHDR_DEST:
if (!zero_out_mutable_opts(exthdr.opth)) {
LIMIT_NETDEBUG(
KERN_WARNING "overrun %sopts\n",
@@ -226,7 +202,6 @@ #else
return -EINVAL;
}
break;
-#endif
case NEXTHDR_ROUTING:
ipv6_rearrange_rthdr(iph, exthdr.rth);
@@ -282,16 +257,13 @@ #endif
}
#ifdef CONFIG_IPV6_MIP6
memcpy(tmp_ext, &top_iph->saddr, extlen);
- err = ipv6_clear_mutable_options(top_iph,
- extlen - sizeof(*tmp_ext) +
- sizeof(*top_iph),
- XFRM_POLICY_OUT);
#else
memcpy(tmp_ext, &top_iph->daddr, extlen);
+#endif
err = ipv6_clear_mutable_options(top_iph,
extlen - sizeof(*tmp_ext) +
- sizeof(*top_iph));
-#endif
+ sizeof(*top_iph),
+ XFRM_POLICY_OUT);
if (err)
goto error_free_iph;
}
@@ -382,13 +354,8 @@ static int ah6_input(struct xfrm_state *
if (!tmp_hdr)
goto out;
memcpy(tmp_hdr, skb->nh.raw, hdr_len);
-#ifdef CONFIG_IPV6_MIP6
if (ipv6_clear_mutable_options(skb->nh.ipv6h, hdr_len, XFRM_POLICY_IN))
goto free_out;
-#else
- if (ipv6_clear_mutable_options(skb->nh.ipv6h, hdr_len))
- goto free_out;
-#endif
skb->nh.ipv6h->priority = 0;
skb->nh.ipv6h->flow_lbl[0] = 0;
skb->nh.ipv6h->flow_lbl[1] = 0;
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 077f626..f4c7629 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -87,7 +87,6 @@ int ipv6_find_tlv(struct sk_buff *skb, i
len -= optlen;
}
/* not_found */
- return -1;
bad:
return -1;
}
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index 7085403..99d116c 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -121,7 +121,8 @@ int mip6_mh_filter(struct sock *sk, stru
&skb->nh.ipv6h->daddr,
mhlen, IPPROTO_MH,
skb_checksum(skb, 0, mhlen, 0))) {
- LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH checksum failed
[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x >
%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]\n",
+ LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH checksum failed "
+ "[" NIP6_FMT " > " NIP6_FMT "]\n",
NIP6(skb->nh.ipv6h->saddr),
NIP6(skb->nh.ipv6h->daddr));
return -1;
@@ -234,7 +235,8 @@ static int mip6_destopt_reject(struct xf
struct timeval stamp;
int err = 0;
- if (unlikely(fl->proto == IPPROTO_MH && fl->fl_mh_type <=
IP6_MH_TYPE_MAX))
+ if (unlikely(fl->proto == IPPROTO_MH &&
+ fl->fl_mh_type <= IP6_MH_TYPE_MAX))
goto out;
if (likely(opt->dsthao)) {
---
commit 95dcd7a0c5e55a36d78c4a6bf0a44fc9a6060fdf
Author: YOSHIFUJI Hideaki <[EMAIL PROTECTED]>
Date: Mon Aug 21 19:18:57 2006 +0900
[IPV6] ROUTE: Routing by Traffic Class.
Signed-off-by: YOSHIFUJI Hideaki <[EMAIL PROTECTED]>
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index 7b4908c..91f6233 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -121,6 +121,9 @@ static int fib6_rule_match(struct fib_ru
!ipv6_prefix_equal(&fl->fl6_src, &r->src.addr, r->src.plen))
return 0;
+ if (r->tclass && r->tclass != ((ntohl(fl->fl6_flowlabel) >> 20) & 0xff))
+ return 0;
+
return 1;
}
---
commit 10204d532f5f8bb379009ba0bee2113bafda72be
Author: YOSHIFUJI Hideaki <[EMAIL PROTECTED]>
Date: Mon Aug 21 19:22:01 2006 +0900
[IPV6] ROUTE: Routing by FWMARK.
Based on patch by Jean Lorchat <[EMAIL PROTECTED]>.
Signed-off-by: YOSHIFUJI Hideaki <[EMAIL PROTECTED]>
diff --git a/include/linux/fib_rules.h b/include/linux/fib_rules.h
index 19a82b6..2987549 100644
--- a/include/linux/fib_rules.h
+++ b/include/linux/fib_rules.h
@@ -34,7 +34,7 @@ enum
FRA_UNUSED3,
FRA_UNUSED4,
FRA_UNUSED5,
- FRA_FWMARK, /* netfilter mark (IPv4) */
+ FRA_FWMARK, /* netfilter mark (IPv4/IPv6) */
FRA_FLOW, /* flow/class id */
FRA_UNUSED6,
FRA_UNUSED7,
diff --git a/include/net/flow.h b/include/net/flow.h
index e052291..3ca210e 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -26,6 +26,7 @@ struct flowi {
struct {
struct in6_addr daddr;
struct in6_addr saddr;
+ __u32 fwmark;
__u32 flowlabel;
} ip6_u;
@@ -42,6 +43,7 @@ #define fld_fwmark nl_u.dn_u.fwmark
#define fld_scope nl_u.dn_u.scope
#define fl6_dst nl_u.ip6_u.daddr
#define fl6_src nl_u.ip6_u.saddr
+#define fl6_fwmark nl_u.ip6_u.fwmark
#define fl6_flowlabel nl_u.ip6_u.flowlabel
#define fl4_dst nl_u.ip4_u.daddr
#define fl4_src nl_u.ip4_u.saddr
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index e523d39..54397ee 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -172,3 +172,10 @@ config IPV6_MULTIPLE_TABLES
---help---
Support multiple routing tables.
+config IPV6_ROUTE_FWMARK
+ bool "IPv6: use netfilter MARK value as routing key"
+ depends on IPV6_MULTIPLE_TABLES && NETFILTER
+ ---help---
+ If you say Y here, you will be able to specify different routes for
+ packets with different mark values (see iptables(8), MARK target).
+
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index 91f6233..aebd9e2 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -26,6 +26,9 @@ struct fib6_rule
struct fib_rule common;
struct rt6key src;
struct rt6key dst;
+#ifdef CONFIG_IPV6_ROUTE_FWMARK
+ u8 fwmark;
+#endif
u8 tclass;
};
@@ -124,6 +127,11 @@ static int fib6_rule_match(struct fib_ru
if (r->tclass && r->tclass != ((ntohl(fl->fl6_flowlabel) >> 20) & 0xff))
return 0;
+#ifdef CONFIG_IPV6_ROUTE_FWMARK
+ if (r->fwmark && (r->fwmark != fl->fl6_fwmark))
+ return 0;
+#endif
+
return 1;
}
@@ -164,6 +172,11 @@ static int fib6_rule_configure(struct fi
nla_memcpy(&rule6->dst.addr, tb[FRA_DST],
sizeof(struct in6_addr));
+#ifdef CONFIG_IPV6_ROUTE_FWMARK
+ if (tb[FRA_FWMARK])
+ rule6->fwmark = nla_get_u32(tb[FRA_FWMARK]);
+#endif
+
rule6->src.plen = frh->src_len;
rule6->dst.plen = frh->dst_len;
rule6->tclass = frh->tos;
@@ -195,6 +208,11 @@ static int fib6_rule_compare(struct fib_
nla_memcmp(tb[FRA_DST], &rule6->dst.addr, sizeof(struct in6_addr)))
return 0;
+#ifdef CONFIG_IPV6_ROUTE_FWMARK
+ if (tb[FRA_FWMARK] && (rule6->fwmark != nla_get_u32(tb[FRA_FWMARK])))
+ return 0;
+#endif
+
return 1;
}
@@ -216,6 +234,11 @@ static int fib6_rule_fill(struct fib_rul
NLA_PUT(skb, FRA_SRC, sizeof(struct in6_addr),
&rule6->src.addr);
+#ifdef CONFIG_IPV6_ROUTE_FWMARK
+ if (rule6->fwmark)
+ NLA_PUT_U32(skb, FRA_FWMARK, rule6->fwmark);
+#endif
+
return 0;
nla_put_failure:
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index c9f74c1..9b50e0c 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -703,6 +703,7 @@ void ip6_route_input(struct sk_buff *skb
.ip6_u = {
.daddr = iph->daddr,
.saddr = iph->saddr,
+ .fwmark = skb->nfmark,
.flowlabel = (* (u32 *) iph)&IPV6_FLOWINFO_MASK,
},
},
---
commit c8cf6b48bd9453d61eddd7b2954b36e9ef96800d
Author: YOSHIFUJI Hideaki <[EMAIL PROTECTED]>
Date: Sun Jun 25 23:54:55 2006 +0900
[NET]: Add common helper functions to convert IPv6/IPv4 address string to
network address structure.
These helpers can be used in netfilter, cifs etc.
Signed-off-by: YOSHIFUJI Hideaki <[EMAIL PROTECTED]>
diff --git a/include/linux/inet.h b/include/linux/inet.h
index 6c5587a..b7c6da7 100644
--- a/include/linux/inet.h
+++ b/include/linux/inet.h
@@ -46,5 +46,7 @@ #ifdef __KERNEL__
#include <linux/types.h>
extern __be32 in_aton(const char *str);
+extern int in4_pton(const char *src, int srclen, u8 *dst, char delim, const
char **end);
+extern int in6_pton(const char *src, int srclen, u8 *dst, char delim, const
char **end);
#endif
#endif /* _LINUX_INET_H */
diff --git a/net/core/utils.c b/net/core/utils.c
index 4f96f38..eb49fe4 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -4,6 +4,7 @@
* Authors:
* net_random Alan Cox
* net_ratelimit Andy Kleen
+ * in{4,6}_pton YOSHIFUJI Hideaki, Copyright (C)2006 USAGI/WIDE Project
*
* Created by Alexey Kuznetsov <[EMAIL PROTECTED]>
*
@@ -190,3 +191,217 @@ __be32 in_aton(const char *str)
}
EXPORT_SYMBOL(in_aton);
+
+#define IN6PTON_XDIGIT 0x00010000
+#define IN6PTON_DIGIT 0x00020000
+#define IN6PTON_COLON_MASK 0x00700000
+#define IN6PTON_COLON_1 0x00100000 /* single : requested */
+#define IN6PTON_COLON_2 0x00200000 /* second : requested */
+#define IN6PTON_COLON_1_2 0x00400000 /* :: requested */
+#define IN6PTON_DOT 0x00800000 /* . */
+#define IN6PTON_DELIM 0x10000000
+#define IN6PTON_NULL 0x20000000 /* first/tail */
+#define IN6PTON_UNKNOWN 0x40000000
+
+static inline int digit2bin(char c, char delim)
+{
+ if (c == delim || c == '\0')
+ return IN6PTON_DELIM;
+ if (c == '.')
+ return IN6PTON_DOT;
+ if (c >= '0' && c <= '9')
+ return (IN6PTON_DIGIT | (c - '0'));
+ return IN6PTON_UNKNOWN;
+}
+
+static inline int xdigit2bin(char c, char delim)
+{
+ if (c == delim || c == '\0')
+ return IN6PTON_DELIM;
+ if (c == ':')
+ return IN6PTON_COLON_MASK;
+ if (c == '.')
+ return IN6PTON_DOT;
+ if (c >= '0' && c <= '9')
+ return (IN6PTON_XDIGIT | IN6PTON_DIGIT| (c - '0'));
+ if (c >= 'a' && c <= 'f')
+ return (IN6PTON_XDIGIT | (c - 'a' + 10));
+ if (c >= 'A' && c <= 'F')
+ return (IN6PTON_XDIGIT | (c - 'A' + 10));
+ return IN6PTON_UNKNOWN;
+}
+
+int in4_pton(const char *src, int srclen,
+ u8 *dst,
+ char delim, const char **end)
+{
+ const char *s;
+ u8 *d;
+ u8 dbuf[4];
+ int ret = 0;
+ int i;
+ int w = 0;
+
+ if (srclen < 0)
+ srclen = strlen(src);
+ s = src;
+ d = dbuf;
+ i = 0;
+ while(1) {
+ int c;
+ c = xdigit2bin(srclen > 0 ? *s : '\0', delim);
+ if (!(c & (IN6PTON_DIGIT | IN6PTON_DOT | IN6PTON_DELIM))) {
+ goto out;
+ }
+ if (c & (IN6PTON_DOT | IN6PTON_DELIM)) {
+ if (w == 0)
+ goto out;
+ *d++ = w & 0xff;
+ w = 0;
+ i++;
+ if (c & IN6PTON_DELIM) {
+ if (i != 4)
+ goto out;
+ break;
+ }
+ goto cont;
+ }
+ w = (w * 10) + c;
+ if ((w & 0xffff) > 255) {
+ goto out;
+ }
+cont:
+ if (i >= 4)
+ goto out;
+ s++;
+ srclen--;
+ }
+ ret = 1;
+ memcpy(dst, dbuf, sizeof(dbuf));
+out:
+ if (end)
+ *end = s;
+ return ret;
+}
+
+EXPORT_SYMBOL(in4_pton);
+
+int in6_pton(const char *src, int srclen,
+ u8 *dst,
+ char delim, const char **end)
+{
+ const char *s, *tok = NULL;
+ u8 *d, *dc = NULL;
+ u8 dbuf[16];
+ int ret = 0;
+ int i;
+ int state = IN6PTON_COLON_1_2 | IN6PTON_XDIGIT | IN6PTON_NULL;
+ int w = 0;
+
+ memset(dbuf, 0, sizeof(dbuf));
+
+ s = src;
+ d = dbuf;
+ if (srclen < 0)
+ srclen = strlen(src);
+
+ printf("srclen=%d\n", srclen);
+
+ while (1) {
+ int c;
+
+ c = xdigit2bin(srclen > 0 ? *s : '\0', delim);
+ if (!(c & state))
+ goto out;
+ if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
+ /* process one 16-bit word */
+ if (!(state & IN6PTON_NULL)) {
+ *d++ = (w >> 8) & 0xff;
+ *d++ = w & 0xff;
+ }
+ w = 0;
+ if (c & IN6PTON_DELIM) {
+ /* We've processed last word */
+ break;
+ }
+ /*
+ * COLON_1 => XDIGIT
+ * COLON_2 => XDIGIT|DELIM
+ * COLON_1_2 => COLON_2
+ */
+ switch (state & IN6PTON_COLON_MASK) {
+ case IN6PTON_COLON_2:
+ dc = d;
+ state = IN6PTON_XDIGIT | IN6PTON_DELIM;
+ if (dc - dbuf >= sizeof(dbuf))
+ state |= IN6PTON_NULL;
+ break;
+ case IN6PTON_COLON_1|IN6PTON_COLON_1_2:
+ state = IN6PTON_XDIGIT | IN6PTON_COLON_2;
+ break;
+ case IN6PTON_COLON_1:
+ state = IN6PTON_XDIGIT;
+ break;
+ case IN6PTON_COLON_1_2:
+ state = IN6PTON_COLON_2;
+ break;
+ default:
+ state = 0;
+ }
+ tok = s + 1;
+ goto cont;
+ }
+
+ if (c & IN6PTON_DOT) {
+ ret = in4_pton(tok ? tok : s, srclen + (int)(s - tok),
d, delim, &s);
+ if (ret > 0) {
+ d += 4;
+ break;
+ }
+ goto out;
+ }
+
+ w = (w << 4) | (0xff & c);
+ state = IN6PTON_COLON_1 | IN6PTON_DELIM;
+ if (!(w & 0xf000)) {
+ state |= IN6PTON_XDIGIT;
+ }
+ if (!dc && d + 2 < dbuf + sizeof(dbuf)) {
+ state |= IN6PTON_COLON_1_2;
+ state &= ~IN6PTON_DELIM;
+ }
+ if (d + 2 >= dbuf + sizeof(dbuf)) {
+ state &= ~(IN6PTON_COLON_1|IN6PTON_COLON_1_2);
+ }
+cont:
+ if ((dc && d + 4 < dbuf + sizeof(dbuf)) ||
+ d + 4 == dbuf + sizeof(dbuf)) {
+ state |= IN6PTON_DOT;
+ }
+ if (d >= dbuf + sizeof(dbuf)) {
+ state &= ~(IN6PTON_XDIGIT|IN6PTON_COLON_MASK);
+ }
+ s++;
+ srclen--;
+ }
+
+ i = 15; d--;
+
+ if (dc) {
+ while(d >= dc)
+ dst[i--] = *d--;
+ while(i >= dc - dbuf)
+ dst[i--] = 0;
+ while(i >= 0)
+ dst[i--] = *d--;
+ } else
+ memcpy(dst, dbuf, sizeof(dbuf));
+
+ ret = 1;
+out:
+ if (end)
+ *end = s;
+ return ret;
+}
+
+EXPORT_SYMBOL(in6_pton);
---
commit 83744e3359ab5b96278dc1332d8e54c4d3507ab5
Author: YOSHIFUJI Hideaki <[EMAIL PROTECTED]>
Date: Mon Jun 19 03:20:32 2006 +0900
[NETFILTER] NF_CONNTRACK_FTP: Use in6_pton() to convert address string.
Signed-off-by: YOSHIFUJI Hideaki <[EMAIL PROTECTED]>
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index 960972d..9dccb40 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -111,101 +111,13 @@ static struct ftp_search {
},
};
-/* This code is based on inet_pton() in glibc-2.2.4 */
static int
get_ipv6_addr(const char *src, size_t dlen, struct in6_addr *dst, u_int8_t
term)
{
- static const char xdigits[] = "0123456789abcdef";
- u_int8_t tmp[16], *tp, *endp, *colonp;
- int ch, saw_xdigit;
- u_int32_t val;
- size_t clen = 0;
-
- tp = memset(tmp, '\0', sizeof(tmp));
- endp = tp + sizeof(tmp);
- colonp = NULL;
-
- /* Leading :: requires some special handling. */
- if (*src == ':'){
- if (*++src != ':') {
- DEBUGP("invalid \":\" at the head of addr\n");
- return 0;
- }
- clen++;
- }
-
- saw_xdigit = 0;
- val = 0;
- while ((clen < dlen) && (*src != term)) {
- const char *pch;
-
- ch = tolower(*src++);
- clen++;
-
- pch = strchr(xdigits, ch);
- if (pch != NULL) {
- val <<= 4;
- val |= (pch - xdigits);
- if (val > 0xffff)
- return 0;
-
- saw_xdigit = 1;
- continue;
- }
- if (ch != ':') {
- DEBUGP("get_ipv6_addr: invalid char. \'%c\'\n", ch);
- return 0;
- }
-
- if (!saw_xdigit) {
- if (colonp) {
- DEBUGP("invalid location of \"::\".\n");
- return 0;
- }
- colonp = tp;
- continue;
- } else if (*src == term) {
- DEBUGP("trancated IPv6 addr\n");
- return 0;
- }
-
- if (tp + 2 > endp)
- return 0;
- *tp++ = (u_int8_t) (val >> 8) & 0xff;
- *tp++ = (u_int8_t) val & 0xff;
-
- saw_xdigit = 0;
- val = 0;
- continue;
- }
- if (saw_xdigit) {
- if (tp + 2 > endp)
- return 0;
- *tp++ = (u_int8_t) (val >> 8) & 0xff;
- *tp++ = (u_int8_t) val & 0xff;
- }
- if (colonp != NULL) {
- /*
- * Since some memmove()'s erroneously fail to handle
- * overlapping regions, we'll do the shift by hand.
- */
- const int n = tp - colonp;
- int i;
-
- if (tp == endp)
- return 0;
-
- for (i = 1; i <= n; i++) {
- endp[- i] = colonp[n - i];
- colonp[n - i] = 0;
- }
- tp = endp;
- }
- if (tp != endp || (*src != term))
- return 0;
-
- memcpy(dst->s6_addr, tmp, sizeof(dst->s6_addr));
- return clen;
+ int ret = in6_pton(src, min_t(size_t, dlen, 0xffff), dst, term, &end);
+ if (ret > 0)
+ return (int)(end - src);
+ return 0;
}
static int try_number(const char *data, size_t dlen, u_int32_t array[],
---
--
YOSHIFUJI Hideaki @ USAGI Project <[EMAIL PROTECTED]>
GPG-FP : 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html