1 /*
2  * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3  */
4 
5 #include <stdio.h>
6 #include <ctype.h>
7 
platform_aton(const char * ip_str)8 unsigned int platform_aton(const char *ip_str)
9 {
10     char c;
11     unsigned char base;
12     unsigned int val = 0;
13     unsigned int parts[4] = { 0 };
14     unsigned int *pp = parts;
15 
16     c = *ip_str;
17     for (;;) {
18         /*
19          * Collect number up to ``.''.
20          * Values are specified as for C:
21          * 0x=hex, 0=octal, 1-9=decimal.
22          */
23         if (!isdigit(c))
24             return 0;
25 
26         val = 0;
27         base = 10;
28         if (c == '0') {
29             c = *++ip_str;
30             if (c == 'x' || c == 'X') {
31                 base = 16;
32                 c = *++ip_str;
33             } else {
34                 base = 8;
35             }
36         }
37         for (;;) {
38             if (isdigit(c)) {
39                 val = (val * base) + (int)(c - '0');
40                 c = *++ip_str;
41             } else if (base == 16 && isxdigit(c)) {
42                 val = (val << 4) | (int)(c + 10 - (islower(c) ? 'a' : 'A'));
43                 c = *++ip_str;
44             } else {
45                 break;
46             }
47         }
48         if (c == '.') {
49             /*
50              * Internet format:
51              *  a.b.c.d
52              *  a.b.c   (with c treated as 16 bits)
53              *  a.b (with b treated as 24 bits)
54              */
55             if (pp >= parts + 3)
56                 return 0;
57             *pp++ = val;
58             c = *++ip_str;
59         } else {
60             break;
61         }
62     }
63     /*
64      * Check for trailing characters.
65      */
66     if (c != '\0' && !isspace(c))
67         return 0;
68     /*
69      * Concoct the address according to
70      * the number of parts specified.
71      */
72     switch (pp - parts + 1) {
73     case 0:
74         return 0; /* initial nondigit */
75     case 1:         /* a -- 32 bits */
76         break;
77     case 2: /* a.b -- 8.24 bits */
78         if (val > 0xffffffUL)
79             return 0;
80         val |= parts[0] << 24;
81         break;
82     case 3: /* a.b.c -- 8.8.16 bits */
83         if (val > 0xffff)
84             return 0;
85         val |= (parts[0] << 24) | (parts[1] << 16);
86         break;
87     case 4: /* a.b.c.d -- 8.8.8.8 bits */
88         if (val > 0xff)
89             return 0;
90         val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
91         break;
92     default:
93         break;
94     }
95 
96     return val;
97 }
98 
platform_is_multicast(const char * ip_str)99 int platform_is_multicast(const char *ip_str)
100 {
101     unsigned int addr_in;
102     addr_in = platform_aton(ip_str);
103     return (addr_in > 0xE00000FF && addr_in <= 0xEFFFFFFF);
104 }
105