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