1 /*
2 20130607
3 Jan Mojzis
4 Public domain.
5 */
6 
7 #include "byte.h"
8 #include "str.h"
9 #include "strtoip.h"
10 #include "strtomultiip.h"
11 
12 static char separators[] = { ',', ' ', '\t', '\n', 0 };
13 
_strtomultiip(unsigned char * ip,long long ipmax,const char * x,int (* op)(unsigned char *,const char *))14 static long long _strtomultiip(unsigned char *ip, long long ipmax, const char *x, int (*op)(unsigned char *, const char *)) {
15 
16     unsigned char data[STRTOMULTIIP_BUFSIZE];
17 
18     long long i, j, k;
19     long long iplen = 0;
20     long long len;
21 
22     if (!x) return 0;
23 
24     byte_zero(ip, ipmax);
25 
26     len = str_len(x);
27     if (len > STRTOMULTIIP_BUFSIZE - 1) {
28         len = STRTOMULTIIP_BUFSIZE - 1;
29         for (j = 0; separators[j]; ++j) len = byte_rchr(x, len, separators[j]);
30     }
31     byte_copy(data, len, x);
32     data[len++] = 0;
33 
34     /* separators ',' ' ' '\t' '\n' */
35     for (i = 0; i < len; ++i) {
36         for (j = 0; separators[j]; ++j) if (data[i] == separators[j]) data[i] = 0;
37     }
38 
39     /* separator '.' - IPv4 backward compatibility */
40     j = byte_chr(data, len, ':');
41     if (j == len) {
42         k = 0;
43         for (i = 0; i < len; ++i) {
44             if (data[i] == 0) k = 0;
45             if (data[i] == '.') if (++k % 4 == 0) data[i] = 0;
46         }
47     }
48 
49     /* parse ip */
50     i = 0;
51     for (j = 0; j < len; ++j) {
52         if (data[j] == 0) {
53             if (iplen + 16 <= ipmax) {
54                 if (op(ip + iplen, (char *)data + i)) {
55                     iplen += 16;
56                 }
57             }
58             i = j + 1;
59         }
60     }
61 
62     return iplen;
63 }
64 
strtomultiip4(unsigned char * ip,long long ipmax,const char * x)65 long long strtomultiip4(unsigned char *ip, long long ipmax, const char *x) {
66     return _strtomultiip(ip, ipmax, x, strtoip4);
67 }
68 
strtomultiip6(unsigned char * ip,long long ipmax,const char * x)69 long long strtomultiip6(unsigned char *ip, long long ipmax, const char *x) {
70     return _strtomultiip(ip, ipmax, x, strtoip6);
71 }
72 
strtomultiip(unsigned char * ip,long long ipmax,const char * x)73 long long strtomultiip(unsigned char *ip, long long ipmax, const char *x) {
74     return _strtomultiip(ip, ipmax, x, strtoip);
75 }
76 
77