ze-filter  (ze-filter-0.8.0-develop-180218)
ze-ipv6.c
Go to the documentation of this file.
1 /*
2  *
3  * ze-filter - Mail Server Filter for sendmail
4  *
5  * Copyright (c) 2001-2018 - Jose-Marcio Martins da Cruz
6  *
7  * Auteur : Jose Marcio Martins da Cruz
8  * jose.marcio.mc@gmail.org
9  *
10  * Historique :
11  * Creation : Sat Jun 23 00:54:01 CEST 2007
12  *
13  * This program is free software, but with restricted license :
14  *
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19  *
20  * More details about ze-filter license can be found at ze-filter
21  * web site : http://foss.jose-marcio.org
22  */
23 
24 
25 #include <ze-sys.h>
26 #include <ze-filter.h>
27 #include <ze-ipv6.h>
28 
29 /* ****************************************************************************
30  * *
31  * *
32  **************************************************************************** */
33 
34 static int charcount(char *s, int c);
35 
36 /* ****************************************************************************
37  * *
38  * *
39  **************************************************************************** */
40 bool
41 ipv6_check_net(net, addr)
42  ipv6_T *net;
43  ipv6_T *addr;
44 {
45  ASSERT(net != NULL);
46  ASSERT(addr != NULL);
47 
48  return TRUE;
49 }
50 
51 /* ****************************************************************************
52  * *
53  * *
54  **************************************************************************** */
55 bool
56 ipv6_cmp(a, b)
57  ipv6_T *a;
58  ipv6_T *b;
59 {
60  return TRUE;
61 }
62 
63 /* ****************************************************************************
64  * *
65  * *
66  **************************************************************************** */
67 void
68 ipv6_expand(sout, sin, size)
69  char *sout;
70  char *sin;
71  size_t size;
72 {
73  ipv6_T ipv6;
74  char buf[8];
75  int i;
76 
77  memset(&ipv6, 0, sizeof (ipv6));
78 
79  ipv6_str2rec(&ipv6, sin);
80 
81  memset(sout, 0, size);
82  for (i = 0; i < 16; i++)
83  {
84  if (strlen(sout) > 0)
85  strlcat(sout, ":", size);
86  snprintf(buf, sizeof (buf), "%x", ipv6.addr[i]);
87  strlcat(sout, buf, size);
88  }
89 }
90 
91 /* ****************************************************************************
92  * *
93  * *
94  **************************************************************************** */
95 bool
96 ipv6_str2rec(addr, sin)
97  ipv6_T *addr;
98  char *sin;
99 {
100  char *p;
101  int i, n;
102  bool result = FALSE;
103 
104  ASSERT(addr != NULL);
105  ASSERT(sin != NULL);
106 
107  memset(addr, 0, sizeof (*addr));
108 
109  strlcpy(addr->str, sin, sizeof (addr->str));
110 
111  p = strstr(sin, "::");
112  if (p != NULL)
113  {
114  p++;
115  p = strstr(p, "::");
116  if (p != NULL)
117  {
118  ZE_MessageWarning(10, " Invalid IPV6 address : %s", sin);
119  goto fin;
120  }
121  }
122 
123  n = 0;
124  p = sin;
125  while (n < 16)
126  {
127  unsigned long u;
128  unsigned int h, l;
129  char *ptr = NULL;
130 
131  errno = 0;
132  u = strtoul(p, &ptr, 16);
133  if (errno != 0)
134  {
135  ZE_MessageWarning(10, " Invalid IPV6 address : %s", sin);
136  goto fin;
137  }
138 
139  if (u >= 0x10000)
140  {
141  ZE_MessageWarning(10, " Invalid IPV6 address : %s", sin);
142  goto fin;
143  }
144 
145  l = u & 0xFF;
146  h = u >> 8;
147  addr->addr[n++] = h;
148  addr->addr[n++] = l;
149  p = ptr;
150 
151  if (p == NULL)
152  break;
153  i = strspn(p, ":");
154  if (i == 0)
155  break;
156  if (i == 1)
157  {
158  p++;
159  continue;
160  }
161  if (i == 2)
162  {
163  p += 2;
164  i = charcount(p, ':');
165  n = 16 - 2 * (i + 1);
166  continue;
167  }
168  break;
169  }
170 
171  addr->prefix = 64;
172  if (*p == '/')
173  {
174  p++;
175  if (*p != '\0')
176  {
177  unsigned int u = 0;
178 
179  errno = 0;
180  u = strtoul(p, NULL, 10);
181  if (errno == 0)
182  {
183  addr->prefix = u;
184  }
185  }
186  }
187 
188  for (i = 0; i < addr->prefix; i++)
189  {
190  int io, ip;
191 
192  io = i / 8;
193  ip = 7 - (i % 8);
194 
195  if (i < addr->prefix)
196  addr->mask[io] |= 1 << ip;
197  }
198 
199  result = TRUE;
200 
201 fin:
202  return result;
203 }
204 
205 /* ****************************************************************************
206  * *
207  * *
208  **************************************************************************** */
209 void
210 ipv6_rec2str(sout, addr, sz)
211  char *sout;
212  ipv6_T *addr;
213  size_t sz;
214 {
215  char tmp[16];
216  int i;
217 
218  ASSERT(sout != NULL);
219  ASSERT(addr != NULL);
220 
221  memset(sout, 0, sz);
222  for (i = 0; i < 8; i++)
223  {
224  int m = 0;
225 
226  if (strlen(sout) > 0)
227  strlcat(sout, ":", sz);
228  m = ((int) addr->addr[2 * i]) << 8 | ((int) addr->addr[2 * i + 1]);
229 
230  snprintf(tmp, sizeof (tmp), "%x", m);
231  strlcat(sout, tmp, sz);
232  }
233  snprintf(tmp, sizeof (tmp), "/%d", addr->prefix);
234  strlcat(sout, tmp, sz);
235 }
236 
237 /* ****************************************************************************
238  * *
239  * *
240  **************************************************************************** */
241 void
242 ipv6_set_prefix(addr, prefix)
243  ipv6_T *addr;
244  int prefix;
245 {
246  int i;
247 
248  ASSERT(addr != NULL);
249 
250  addr->prefix = prefix;
251 
252  memset(addr->mask, 0, sizeof (addr->mask));
253  for (i = 0; i < prefix; i++)
254  {
255  int io, ip;
256 
257  io = i / 8;
258  ip = 7 - (i % 8);
259 
260  if (i < prefix)
261  addr->mask[io] |= 1 << ip;
262  }
263 }
264 
265 /* ****************************************************************************
266  * *
267  * *
268  **************************************************************************** */
269 void
270 ipv6_subnet(net, addr)
271  ipv6_T *net;
272  ipv6_T *addr;
273 {
274  int i;
275 
276  ASSERT(addr != NULL);
277  ASSERT(net != NULL);
278 
279  *net = *addr;
280 
281  for (i = 0; i < 16; i++)
282  net->addr[i] &= net->mask[i];
283 }
284 
285 /* ****************************************************************************
286  * *
287  * *
288  **************************************************************************** */
289 void
290 ipv6_prefix_str(addr, buf, size, n)
291  ipv6_T *addr;
292  char *buf;
293  size_t size;
294  int n;
295 {
296  ipv6_T ip, net;
297 
298  ASSERT(addr != NULL);
299  ASSERT(buf != NULL && size > 0);
300 
301  ip = *addr;
302  ipv6_set_prefix(&ip, n);
303  ipv6_subnet(&net, &ip);
304  ipv6_rec2str(buf, &net, size);
305 }
306 
307 /* ****************************************************************************
308  * *
309  * *
310  **************************************************************************** */
311 static int
312 charcount(s, c)
313  char *s;
314  int c;
315 {
316  int n = 0;
317 
318  for (n = 0; s != NULL && *s != '\0' && (s = strchr(s, c)) != NULL; s++)
319  n++;
320  return n;
321 }
Definition: ze-ipv6.h:32
int prefix
Definition: ze-ipv6.h:36
#define ASSERT(a)
Definition: macros.h:27
#define FALSE
Definition: macros.h:160
#define strlcpy
Definition: zeString.h:32
bool ipv6_check_net(ipv6_T *net, ipv6_T *addr)
Definition: ze-ipv6.c:41
char str[64]
Definition: ze-ipv6.h:37
bool ipv6_cmp(ipv6_T *a, ipv6_T *b)
Definition: ze-ipv6.c:56
#define strlcat
Definition: zeString.h:28
#define strchr
Definition: ze-sys.h:218
void ipv6_set_prefix(ipv6_T *addr, int prefix)
Definition: ze-ipv6.c:242
bool ipv6_str2rec(ipv6_T *addr, char *sin)
Definition: ze-ipv6.c:96
void ipv6_expand(char *sout, char *sin, size_t size)
Definition: ze-ipv6.c:68
uint8_t mask[16]
Definition: ze-ipv6.h:35
#define TRUE
Definition: macros.h:157
#define ZE_MessageWarning(level,...)
Definition: zeSyslog.h:92
uint8_t addr[16]
Definition: ze-ipv6.h:34
void ipv6_subnet(ipv6_T *net, ipv6_T *addr)
Definition: ze-ipv6.c:270
void ipv6_prefix_str(ipv6_T *addr, char *buf, size_t size, int n)
Definition: ze-ipv6.c:290
void ipv6_rec2str(char *sout, ipv6_T *addr, size_t sz)
Definition: ze-ipv6.c:210