xref: /linux-6.15/net/core/utils.c (revision 1aaec67f)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  *	Generic address resultion entity
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  *	Authors:
51da177e4SLinus Torvalds  *	net_random Alan Cox
61da177e4SLinus Torvalds  *	net_ratelimit Andy Kleen
7*1aaec67fSYOSHIFUJI Hideaki  *	in{4,6}_pton YOSHIFUJI Hideaki, Copyright (C)2006 USAGI/WIDE Project
81da177e4SLinus Torvalds  *
91da177e4SLinus Torvalds  *	Created by Alexey Kuznetsov <[email protected]>
101da177e4SLinus Torvalds  *
111da177e4SLinus Torvalds  *	This program is free software; you can redistribute it and/or
121da177e4SLinus Torvalds  *      modify it under the terms of the GNU General Public License
131da177e4SLinus Torvalds  *      as published by the Free Software Foundation; either version
141da177e4SLinus Torvalds  *      2 of the License, or (at your option) any later version.
151da177e4SLinus Torvalds  */
161da177e4SLinus Torvalds 
171da177e4SLinus Torvalds #include <linux/module.h>
181da177e4SLinus Torvalds #include <linux/jiffies.h>
191da177e4SLinus Torvalds #include <linux/kernel.h>
2020380731SArnaldo Carvalho de Melo #include <linux/inet.h>
211da177e4SLinus Torvalds #include <linux/mm.h>
2220380731SArnaldo Carvalho de Melo #include <linux/net.h>
231da177e4SLinus Torvalds #include <linux/string.h>
241da177e4SLinus Torvalds #include <linux/types.h>
251da177e4SLinus Torvalds #include <linux/random.h>
261da177e4SLinus Torvalds #include <linux/percpu.h>
271da177e4SLinus Torvalds #include <linux/init.h>
281da177e4SLinus Torvalds 
295e43db77SMatt Mackall #include <asm/byteorder.h>
301da177e4SLinus Torvalds #include <asm/system.h>
311da177e4SLinus Torvalds #include <asm/uaccess.h>
321da177e4SLinus Torvalds 
331da177e4SLinus Torvalds /*
341da177e4SLinus Torvalds   This is a maximally equidistributed combined Tausworthe generator
351da177e4SLinus Torvalds   based on code from GNU Scientific Library 1.5 (30 Jun 2004)
361da177e4SLinus Torvalds 
371da177e4SLinus Torvalds    x_n = (s1_n ^ s2_n ^ s3_n)
381da177e4SLinus Torvalds 
391da177e4SLinus Torvalds    s1_{n+1} = (((s1_n & 4294967294) <<12) ^ (((s1_n <<13) ^ s1_n) >>19))
401da177e4SLinus Torvalds    s2_{n+1} = (((s2_n & 4294967288) << 4) ^ (((s2_n << 2) ^ s2_n) >>25))
411da177e4SLinus Torvalds    s3_{n+1} = (((s3_n & 4294967280) <<17) ^ (((s3_n << 3) ^ s3_n) >>11))
421da177e4SLinus Torvalds 
431da177e4SLinus Torvalds    The period of this generator is about 2^88.
441da177e4SLinus Torvalds 
451da177e4SLinus Torvalds    From: P. L'Ecuyer, "Maximally Equidistributed Combined Tausworthe
461da177e4SLinus Torvalds    Generators", Mathematics of Computation, 65, 213 (1996), 203--213.
471da177e4SLinus Torvalds 
481da177e4SLinus Torvalds    This is available on the net from L'Ecuyer's home page,
491da177e4SLinus Torvalds 
501da177e4SLinus Torvalds    http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps
511da177e4SLinus Torvalds    ftp://ftp.iro.umontreal.ca/pub/simulation/lecuyer/papers/tausme.ps
521da177e4SLinus Torvalds 
531da177e4SLinus Torvalds    There is an erratum in the paper "Tables of Maximally
541da177e4SLinus Torvalds    Equidistributed Combined LFSR Generators", Mathematics of
551da177e4SLinus Torvalds    Computation, 68, 225 (1999), 261--269:
561da177e4SLinus Torvalds    http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps
571da177e4SLinus Torvalds 
581da177e4SLinus Torvalds         ... the k_j most significant bits of z_j must be non-
591da177e4SLinus Torvalds         zero, for each j. (Note: this restriction also applies to the
601da177e4SLinus Torvalds         computer code given in [4], but was mistakenly not mentioned in
611da177e4SLinus Torvalds         that paper.)
621da177e4SLinus Torvalds 
631da177e4SLinus Torvalds    This affects the seeding procedure by imposing the requirement
641da177e4SLinus Torvalds    s1 > 1, s2 > 7, s3 > 15.
651da177e4SLinus Torvalds 
661da177e4SLinus Torvalds */
671da177e4SLinus Torvalds struct nrnd_state {
681da177e4SLinus Torvalds 	u32 s1, s2, s3;
691da177e4SLinus Torvalds };
701da177e4SLinus Torvalds 
711da177e4SLinus Torvalds static DEFINE_PER_CPU(struct nrnd_state, net_rand_state);
721da177e4SLinus Torvalds 
731da177e4SLinus Torvalds static u32 __net_random(struct nrnd_state *state)
741da177e4SLinus Torvalds {
751da177e4SLinus Torvalds #define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b)
761da177e4SLinus Torvalds 
771da177e4SLinus Torvalds 	state->s1 = TAUSWORTHE(state->s1, 13, 19, 4294967294UL, 12);
781da177e4SLinus Torvalds 	state->s2 = TAUSWORTHE(state->s2, 2, 25, 4294967288UL, 4);
791da177e4SLinus Torvalds 	state->s3 = TAUSWORTHE(state->s3, 3, 11, 4294967280UL, 17);
801da177e4SLinus Torvalds 
811da177e4SLinus Torvalds 	return (state->s1 ^ state->s2 ^ state->s3);
821da177e4SLinus Torvalds }
831da177e4SLinus Torvalds 
841da177e4SLinus Torvalds static void __net_srandom(struct nrnd_state *state, unsigned long s)
851da177e4SLinus Torvalds {
861da177e4SLinus Torvalds 	if (s == 0)
871da177e4SLinus Torvalds 		s = 1;      /* default seed is 1 */
881da177e4SLinus Torvalds 
891da177e4SLinus Torvalds #define LCG(n) (69069 * n)
901da177e4SLinus Torvalds 	state->s1 = LCG(s);
911da177e4SLinus Torvalds 	state->s2 = LCG(state->s1);
921da177e4SLinus Torvalds 	state->s3 = LCG(state->s2);
931da177e4SLinus Torvalds 
941da177e4SLinus Torvalds 	/* "warm it up" */
951da177e4SLinus Torvalds 	__net_random(state);
961da177e4SLinus Torvalds 	__net_random(state);
971da177e4SLinus Torvalds 	__net_random(state);
981da177e4SLinus Torvalds 	__net_random(state);
991da177e4SLinus Torvalds 	__net_random(state);
1001da177e4SLinus Torvalds 	__net_random(state);
1011da177e4SLinus Torvalds }
1021da177e4SLinus Torvalds 
1031da177e4SLinus Torvalds 
1041da177e4SLinus Torvalds unsigned long net_random(void)
1051da177e4SLinus Torvalds {
1061da177e4SLinus Torvalds 	unsigned long r;
1071da177e4SLinus Torvalds 	struct nrnd_state *state = &get_cpu_var(net_rand_state);
1081da177e4SLinus Torvalds 	r = __net_random(state);
1091da177e4SLinus Torvalds 	put_cpu_var(state);
1101da177e4SLinus Torvalds 	return r;
1111da177e4SLinus Torvalds }
1121da177e4SLinus Torvalds 
1131da177e4SLinus Torvalds 
1141da177e4SLinus Torvalds void net_srandom(unsigned long entropy)
1151da177e4SLinus Torvalds {
1161da177e4SLinus Torvalds 	struct nrnd_state *state = &get_cpu_var(net_rand_state);
1171da177e4SLinus Torvalds 	__net_srandom(state, state->s1^entropy);
1181da177e4SLinus Torvalds 	put_cpu_var(state);
1191da177e4SLinus Torvalds }
1201da177e4SLinus Torvalds 
1211da177e4SLinus Torvalds void __init net_random_init(void)
1221da177e4SLinus Torvalds {
1231da177e4SLinus Torvalds 	int i;
1241da177e4SLinus Torvalds 
1256f912042SKAMEZAWA Hiroyuki 	for_each_possible_cpu(i) {
1261da177e4SLinus Torvalds 		struct nrnd_state *state = &per_cpu(net_rand_state,i);
1271da177e4SLinus Torvalds 		__net_srandom(state, i+jiffies);
1281da177e4SLinus Torvalds 	}
1291da177e4SLinus Torvalds }
1301da177e4SLinus Torvalds 
1311da177e4SLinus Torvalds static int net_random_reseed(void)
1321da177e4SLinus Torvalds {
1331da177e4SLinus Torvalds 	int i;
13485575112SSuresh Siddha 	unsigned long seed;
1351da177e4SLinus Torvalds 
1366f912042SKAMEZAWA Hiroyuki 	for_each_possible_cpu(i) {
1371da177e4SLinus Torvalds 		struct nrnd_state *state = &per_cpu(net_rand_state,i);
13885575112SSuresh Siddha 
13985575112SSuresh Siddha 		get_random_bytes(&seed, sizeof(seed));
14085575112SSuresh Siddha 		__net_srandom(state, seed);
1411da177e4SLinus Torvalds 	}
1421da177e4SLinus Torvalds 	return 0;
1431da177e4SLinus Torvalds }
1441da177e4SLinus Torvalds late_initcall(net_random_reseed);
1451da177e4SLinus Torvalds 
1461da177e4SLinus Torvalds int net_msg_cost = 5*HZ;
1471da177e4SLinus Torvalds int net_msg_burst = 10;
1481da177e4SLinus Torvalds 
1491da177e4SLinus Torvalds /*
1501da177e4SLinus Torvalds  * All net warning printk()s should be guarded by this function.
1511da177e4SLinus Torvalds  */
1521da177e4SLinus Torvalds int net_ratelimit(void)
1531da177e4SLinus Torvalds {
1541da177e4SLinus Torvalds 	return __printk_ratelimit(net_msg_cost, net_msg_burst);
1551da177e4SLinus Torvalds }
1561da177e4SLinus Torvalds 
1571da177e4SLinus Torvalds EXPORT_SYMBOL(net_random);
1581da177e4SLinus Torvalds EXPORT_SYMBOL(net_ratelimit);
1591da177e4SLinus Torvalds EXPORT_SYMBOL(net_srandom);
1605e43db77SMatt Mackall 
1615e43db77SMatt Mackall /*
1625e43db77SMatt Mackall  * Convert an ASCII string to binary IP.
1635e43db77SMatt Mackall  * This is outside of net/ipv4/ because various code that uses IP addresses
1645e43db77SMatt Mackall  * is otherwise not dependent on the TCP/IP stack.
1655e43db77SMatt Mackall  */
1665e43db77SMatt Mackall 
167a2167dc6SAlexey Dobriyan __be32 in_aton(const char *str)
1685e43db77SMatt Mackall {
1695e43db77SMatt Mackall 	unsigned long l;
1705e43db77SMatt Mackall 	unsigned int val;
1715e43db77SMatt Mackall 	int i;
1725e43db77SMatt Mackall 
1735e43db77SMatt Mackall 	l = 0;
1745e43db77SMatt Mackall 	for (i = 0; i < 4; i++)
1755e43db77SMatt Mackall 	{
1765e43db77SMatt Mackall 		l <<= 8;
1775e43db77SMatt Mackall 		if (*str != '\0')
1785e43db77SMatt Mackall 		{
1795e43db77SMatt Mackall 			val = 0;
1801e2e5659SMitch Williams 			while (*str != '\0' && *str != '.' && *str != '\n')
1815e43db77SMatt Mackall 			{
1825e43db77SMatt Mackall 				val *= 10;
1835e43db77SMatt Mackall 				val += *str - '0';
1845e43db77SMatt Mackall 				str++;
1855e43db77SMatt Mackall 			}
1865e43db77SMatt Mackall 			l |= val;
1875e43db77SMatt Mackall 			if (*str != '\0')
1885e43db77SMatt Mackall 				str++;
1895e43db77SMatt Mackall 		}
1905e43db77SMatt Mackall 	}
1915e43db77SMatt Mackall 	return(htonl(l));
1925e43db77SMatt Mackall }
1935e43db77SMatt Mackall 
1945e43db77SMatt Mackall EXPORT_SYMBOL(in_aton);
195*1aaec67fSYOSHIFUJI Hideaki 
196*1aaec67fSYOSHIFUJI Hideaki #define IN6PTON_XDIGIT		0x00010000
197*1aaec67fSYOSHIFUJI Hideaki #define IN6PTON_DIGIT		0x00020000
198*1aaec67fSYOSHIFUJI Hideaki #define IN6PTON_COLON_MASK	0x00700000
199*1aaec67fSYOSHIFUJI Hideaki #define IN6PTON_COLON_1		0x00100000	/* single : requested */
200*1aaec67fSYOSHIFUJI Hideaki #define IN6PTON_COLON_2		0x00200000	/* second : requested */
201*1aaec67fSYOSHIFUJI Hideaki #define IN6PTON_COLON_1_2	0x00400000	/* :: requested */
202*1aaec67fSYOSHIFUJI Hideaki #define IN6PTON_DOT		0x00800000	/* . */
203*1aaec67fSYOSHIFUJI Hideaki #define IN6PTON_DELIM		0x10000000
204*1aaec67fSYOSHIFUJI Hideaki #define IN6PTON_NULL		0x20000000	/* first/tail */
205*1aaec67fSYOSHIFUJI Hideaki #define IN6PTON_UNKNOWN		0x40000000
206*1aaec67fSYOSHIFUJI Hideaki 
207*1aaec67fSYOSHIFUJI Hideaki static inline int digit2bin(char c, char delim)
208*1aaec67fSYOSHIFUJI Hideaki {
209*1aaec67fSYOSHIFUJI Hideaki 	if (c == delim || c == '\0')
210*1aaec67fSYOSHIFUJI Hideaki 		return IN6PTON_DELIM;
211*1aaec67fSYOSHIFUJI Hideaki 	if (c == '.')
212*1aaec67fSYOSHIFUJI Hideaki 		return IN6PTON_DOT;
213*1aaec67fSYOSHIFUJI Hideaki 	if (c >= '0' && c <= '9')
214*1aaec67fSYOSHIFUJI Hideaki 		return (IN6PTON_DIGIT | (c - '0'));
215*1aaec67fSYOSHIFUJI Hideaki 	return IN6PTON_UNKNOWN;
216*1aaec67fSYOSHIFUJI Hideaki }
217*1aaec67fSYOSHIFUJI Hideaki 
218*1aaec67fSYOSHIFUJI Hideaki static inline int xdigit2bin(char c, char delim)
219*1aaec67fSYOSHIFUJI Hideaki {
220*1aaec67fSYOSHIFUJI Hideaki 	if (c == delim || c == '\0')
221*1aaec67fSYOSHIFUJI Hideaki 		return IN6PTON_DELIM;
222*1aaec67fSYOSHIFUJI Hideaki 	if (c == ':')
223*1aaec67fSYOSHIFUJI Hideaki 		return IN6PTON_COLON_MASK;
224*1aaec67fSYOSHIFUJI Hideaki 	if (c == '.')
225*1aaec67fSYOSHIFUJI Hideaki 		return IN6PTON_DOT;
226*1aaec67fSYOSHIFUJI Hideaki 	if (c >= '0' && c <= '9')
227*1aaec67fSYOSHIFUJI Hideaki 		return (IN6PTON_XDIGIT | IN6PTON_DIGIT| (c - '0'));
228*1aaec67fSYOSHIFUJI Hideaki 	if (c >= 'a' && c <= 'f')
229*1aaec67fSYOSHIFUJI Hideaki 		return (IN6PTON_XDIGIT | (c - 'a' + 10));
230*1aaec67fSYOSHIFUJI Hideaki 	if (c >= 'A' && c <= 'F')
231*1aaec67fSYOSHIFUJI Hideaki 		return (IN6PTON_XDIGIT | (c - 'A' + 10));
232*1aaec67fSYOSHIFUJI Hideaki 	return IN6PTON_UNKNOWN;
233*1aaec67fSYOSHIFUJI Hideaki }
234*1aaec67fSYOSHIFUJI Hideaki 
235*1aaec67fSYOSHIFUJI Hideaki int in4_pton(const char *src, int srclen,
236*1aaec67fSYOSHIFUJI Hideaki 	     u8 *dst,
237*1aaec67fSYOSHIFUJI Hideaki 	     char delim, const char **end)
238*1aaec67fSYOSHIFUJI Hideaki {
239*1aaec67fSYOSHIFUJI Hideaki 	const char *s;
240*1aaec67fSYOSHIFUJI Hideaki 	u8 *d;
241*1aaec67fSYOSHIFUJI Hideaki 	u8 dbuf[4];
242*1aaec67fSYOSHIFUJI Hideaki 	int ret = 0;
243*1aaec67fSYOSHIFUJI Hideaki 	int i;
244*1aaec67fSYOSHIFUJI Hideaki 	int w = 0;
245*1aaec67fSYOSHIFUJI Hideaki 
246*1aaec67fSYOSHIFUJI Hideaki 	if (srclen < 0)
247*1aaec67fSYOSHIFUJI Hideaki 		srclen = strlen(src);
248*1aaec67fSYOSHIFUJI Hideaki 	s = src;
249*1aaec67fSYOSHIFUJI Hideaki 	d = dbuf;
250*1aaec67fSYOSHIFUJI Hideaki 	i = 0;
251*1aaec67fSYOSHIFUJI Hideaki 	while(1) {
252*1aaec67fSYOSHIFUJI Hideaki 		int c;
253*1aaec67fSYOSHIFUJI Hideaki 		c = xdigit2bin(srclen > 0 ? *s : '\0', delim);
254*1aaec67fSYOSHIFUJI Hideaki 		if (!(c & (IN6PTON_DIGIT | IN6PTON_DOT | IN6PTON_DELIM))) {
255*1aaec67fSYOSHIFUJI Hideaki 			goto out;
256*1aaec67fSYOSHIFUJI Hideaki 		}
257*1aaec67fSYOSHIFUJI Hideaki 		if (c & (IN6PTON_DOT | IN6PTON_DELIM)) {
258*1aaec67fSYOSHIFUJI Hideaki 			if (w == 0)
259*1aaec67fSYOSHIFUJI Hideaki 				goto out;
260*1aaec67fSYOSHIFUJI Hideaki 			*d++ = w & 0xff;
261*1aaec67fSYOSHIFUJI Hideaki 			w = 0;
262*1aaec67fSYOSHIFUJI Hideaki 			i++;
263*1aaec67fSYOSHIFUJI Hideaki 			if (c & IN6PTON_DELIM) {
264*1aaec67fSYOSHIFUJI Hideaki 				if (i != 4)
265*1aaec67fSYOSHIFUJI Hideaki 					goto out;
266*1aaec67fSYOSHIFUJI Hideaki 				break;
267*1aaec67fSYOSHIFUJI Hideaki 			}
268*1aaec67fSYOSHIFUJI Hideaki 			goto cont;
269*1aaec67fSYOSHIFUJI Hideaki 		}
270*1aaec67fSYOSHIFUJI Hideaki 		w = (w * 10) + c;
271*1aaec67fSYOSHIFUJI Hideaki 		if ((w & 0xffff) > 255) {
272*1aaec67fSYOSHIFUJI Hideaki 			goto out;
273*1aaec67fSYOSHIFUJI Hideaki 		}
274*1aaec67fSYOSHIFUJI Hideaki cont:
275*1aaec67fSYOSHIFUJI Hideaki 		if (i >= 4)
276*1aaec67fSYOSHIFUJI Hideaki 			goto out;
277*1aaec67fSYOSHIFUJI Hideaki 		s++;
278*1aaec67fSYOSHIFUJI Hideaki 		srclen--;
279*1aaec67fSYOSHIFUJI Hideaki 	}
280*1aaec67fSYOSHIFUJI Hideaki 	ret = 1;
281*1aaec67fSYOSHIFUJI Hideaki 	memcpy(dst, dbuf, sizeof(dbuf));
282*1aaec67fSYOSHIFUJI Hideaki out:
283*1aaec67fSYOSHIFUJI Hideaki 	if (end)
284*1aaec67fSYOSHIFUJI Hideaki 		*end = s;
285*1aaec67fSYOSHIFUJI Hideaki 	return ret;
286*1aaec67fSYOSHIFUJI Hideaki }
287*1aaec67fSYOSHIFUJI Hideaki 
288*1aaec67fSYOSHIFUJI Hideaki EXPORT_SYMBOL(in4_pton);
289*1aaec67fSYOSHIFUJI Hideaki 
290*1aaec67fSYOSHIFUJI Hideaki int in6_pton(const char *src, int srclen,
291*1aaec67fSYOSHIFUJI Hideaki 	     u8 *dst,
292*1aaec67fSYOSHIFUJI Hideaki 	     char delim, const char **end)
293*1aaec67fSYOSHIFUJI Hideaki {
294*1aaec67fSYOSHIFUJI Hideaki 	const char *s, *tok = NULL;
295*1aaec67fSYOSHIFUJI Hideaki 	u8 *d, *dc = NULL;
296*1aaec67fSYOSHIFUJI Hideaki 	u8 dbuf[16];
297*1aaec67fSYOSHIFUJI Hideaki 	int ret = 0;
298*1aaec67fSYOSHIFUJI Hideaki 	int i;
299*1aaec67fSYOSHIFUJI Hideaki 	int state = IN6PTON_COLON_1_2 | IN6PTON_XDIGIT | IN6PTON_NULL;
300*1aaec67fSYOSHIFUJI Hideaki 	int w = 0;
301*1aaec67fSYOSHIFUJI Hideaki 
302*1aaec67fSYOSHIFUJI Hideaki 	memset(dbuf, 0, sizeof(dbuf));
303*1aaec67fSYOSHIFUJI Hideaki 
304*1aaec67fSYOSHIFUJI Hideaki 	s = src;
305*1aaec67fSYOSHIFUJI Hideaki 	d = dbuf;
306*1aaec67fSYOSHIFUJI Hideaki 	if (srclen < 0)
307*1aaec67fSYOSHIFUJI Hideaki 		srclen = strlen(src);
308*1aaec67fSYOSHIFUJI Hideaki 
309*1aaec67fSYOSHIFUJI Hideaki 	printf("srclen=%d\n", srclen);
310*1aaec67fSYOSHIFUJI Hideaki 
311*1aaec67fSYOSHIFUJI Hideaki 	while (1) {
312*1aaec67fSYOSHIFUJI Hideaki 		int c;
313*1aaec67fSYOSHIFUJI Hideaki 
314*1aaec67fSYOSHIFUJI Hideaki 		c = xdigit2bin(srclen > 0 ? *s : '\0', delim);
315*1aaec67fSYOSHIFUJI Hideaki 		if (!(c & state))
316*1aaec67fSYOSHIFUJI Hideaki 			goto out;
317*1aaec67fSYOSHIFUJI Hideaki 		if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
318*1aaec67fSYOSHIFUJI Hideaki 			/* process one 16-bit word */
319*1aaec67fSYOSHIFUJI Hideaki 			if (!(state & IN6PTON_NULL)) {
320*1aaec67fSYOSHIFUJI Hideaki 				*d++ = (w >> 8) & 0xff;
321*1aaec67fSYOSHIFUJI Hideaki 				*d++ = w & 0xff;
322*1aaec67fSYOSHIFUJI Hideaki 			}
323*1aaec67fSYOSHIFUJI Hideaki 			w = 0;
324*1aaec67fSYOSHIFUJI Hideaki 			if (c & IN6PTON_DELIM) {
325*1aaec67fSYOSHIFUJI Hideaki 				/* We've processed last word */
326*1aaec67fSYOSHIFUJI Hideaki 				break;
327*1aaec67fSYOSHIFUJI Hideaki 			}
328*1aaec67fSYOSHIFUJI Hideaki 			/*
329*1aaec67fSYOSHIFUJI Hideaki 			 * COLON_1 => XDIGIT
330*1aaec67fSYOSHIFUJI Hideaki 			 * COLON_2 => XDIGIT|DELIM
331*1aaec67fSYOSHIFUJI Hideaki 			 * COLON_1_2 => COLON_2
332*1aaec67fSYOSHIFUJI Hideaki 			 */
333*1aaec67fSYOSHIFUJI Hideaki 			switch (state & IN6PTON_COLON_MASK) {
334*1aaec67fSYOSHIFUJI Hideaki 			case IN6PTON_COLON_2:
335*1aaec67fSYOSHIFUJI Hideaki 				dc = d;
336*1aaec67fSYOSHIFUJI Hideaki 				state = IN6PTON_XDIGIT | IN6PTON_DELIM;
337*1aaec67fSYOSHIFUJI Hideaki 				if (dc - dbuf >= sizeof(dbuf))
338*1aaec67fSYOSHIFUJI Hideaki 					state |= IN6PTON_NULL;
339*1aaec67fSYOSHIFUJI Hideaki 				break;
340*1aaec67fSYOSHIFUJI Hideaki 			case IN6PTON_COLON_1|IN6PTON_COLON_1_2:
341*1aaec67fSYOSHIFUJI Hideaki 				state = IN6PTON_XDIGIT | IN6PTON_COLON_2;
342*1aaec67fSYOSHIFUJI Hideaki 				break;
343*1aaec67fSYOSHIFUJI Hideaki 			case IN6PTON_COLON_1:
344*1aaec67fSYOSHIFUJI Hideaki 				state = IN6PTON_XDIGIT;
345*1aaec67fSYOSHIFUJI Hideaki 				break;
346*1aaec67fSYOSHIFUJI Hideaki 			case IN6PTON_COLON_1_2:
347*1aaec67fSYOSHIFUJI Hideaki 				state = IN6PTON_COLON_2;
348*1aaec67fSYOSHIFUJI Hideaki 				break;
349*1aaec67fSYOSHIFUJI Hideaki 			default:
350*1aaec67fSYOSHIFUJI Hideaki 				state = 0;
351*1aaec67fSYOSHIFUJI Hideaki 			}
352*1aaec67fSYOSHIFUJI Hideaki 			tok = s + 1;
353*1aaec67fSYOSHIFUJI Hideaki 			goto cont;
354*1aaec67fSYOSHIFUJI Hideaki 		}
355*1aaec67fSYOSHIFUJI Hideaki 
356*1aaec67fSYOSHIFUJI Hideaki 		if (c & IN6PTON_DOT) {
357*1aaec67fSYOSHIFUJI Hideaki 			ret = in4_pton(tok ? tok : s, srclen + (int)(s - tok), d, delim, &s);
358*1aaec67fSYOSHIFUJI Hideaki 			if (ret > 0) {
359*1aaec67fSYOSHIFUJI Hideaki 				d += 4;
360*1aaec67fSYOSHIFUJI Hideaki 				break;
361*1aaec67fSYOSHIFUJI Hideaki 			}
362*1aaec67fSYOSHIFUJI Hideaki 			goto out;
363*1aaec67fSYOSHIFUJI Hideaki 		}
364*1aaec67fSYOSHIFUJI Hideaki 
365*1aaec67fSYOSHIFUJI Hideaki 		w = (w << 4) | (0xff & c);
366*1aaec67fSYOSHIFUJI Hideaki 		state = IN6PTON_COLON_1 | IN6PTON_DELIM;
367*1aaec67fSYOSHIFUJI Hideaki 		if (!(w & 0xf000)) {
368*1aaec67fSYOSHIFUJI Hideaki 			state |= IN6PTON_XDIGIT;
369*1aaec67fSYOSHIFUJI Hideaki 		}
370*1aaec67fSYOSHIFUJI Hideaki 		if (!dc && d + 2 < dbuf + sizeof(dbuf)) {
371*1aaec67fSYOSHIFUJI Hideaki 			state |= IN6PTON_COLON_1_2;
372*1aaec67fSYOSHIFUJI Hideaki 			state &= ~IN6PTON_DELIM;
373*1aaec67fSYOSHIFUJI Hideaki 		}
374*1aaec67fSYOSHIFUJI Hideaki 		if (d + 2 >= dbuf + sizeof(dbuf)) {
375*1aaec67fSYOSHIFUJI Hideaki 			state &= ~(IN6PTON_COLON_1|IN6PTON_COLON_1_2);
376*1aaec67fSYOSHIFUJI Hideaki 		}
377*1aaec67fSYOSHIFUJI Hideaki cont:
378*1aaec67fSYOSHIFUJI Hideaki 		if ((dc && d + 4 < dbuf + sizeof(dbuf)) ||
379*1aaec67fSYOSHIFUJI Hideaki 		    d + 4 == dbuf + sizeof(dbuf)) {
380*1aaec67fSYOSHIFUJI Hideaki 			state |= IN6PTON_DOT;
381*1aaec67fSYOSHIFUJI Hideaki 		}
382*1aaec67fSYOSHIFUJI Hideaki 		if (d >= dbuf + sizeof(dbuf)) {
383*1aaec67fSYOSHIFUJI Hideaki 			state &= ~(IN6PTON_XDIGIT|IN6PTON_COLON_MASK);
384*1aaec67fSYOSHIFUJI Hideaki 		}
385*1aaec67fSYOSHIFUJI Hideaki 		s++;
386*1aaec67fSYOSHIFUJI Hideaki 		srclen--;
387*1aaec67fSYOSHIFUJI Hideaki 	}
388*1aaec67fSYOSHIFUJI Hideaki 
389*1aaec67fSYOSHIFUJI Hideaki 	i = 15; d--;
390*1aaec67fSYOSHIFUJI Hideaki 
391*1aaec67fSYOSHIFUJI Hideaki 	if (dc) {
392*1aaec67fSYOSHIFUJI Hideaki 		while(d >= dc)
393*1aaec67fSYOSHIFUJI Hideaki 			dst[i--] = *d--;
394*1aaec67fSYOSHIFUJI Hideaki 		while(i >= dc - dbuf)
395*1aaec67fSYOSHIFUJI Hideaki 			dst[i--] = 0;
396*1aaec67fSYOSHIFUJI Hideaki 		while(i >= 0)
397*1aaec67fSYOSHIFUJI Hideaki 			dst[i--] = *d--;
398*1aaec67fSYOSHIFUJI Hideaki 	} else
399*1aaec67fSYOSHIFUJI Hideaki 		memcpy(dst, dbuf, sizeof(dbuf));
400*1aaec67fSYOSHIFUJI Hideaki 
401*1aaec67fSYOSHIFUJI Hideaki 	ret = 1;
402*1aaec67fSYOSHIFUJI Hideaki out:
403*1aaec67fSYOSHIFUJI Hideaki 	if (end)
404*1aaec67fSYOSHIFUJI Hideaki 		*end = s;
405*1aaec67fSYOSHIFUJI Hideaki 	return ret;
406*1aaec67fSYOSHIFUJI Hideaki }
407*1aaec67fSYOSHIFUJI Hideaki 
408*1aaec67fSYOSHIFUJI Hideaki EXPORT_SYMBOL(in6_pton);
409