ucspi-ssl  0.99e
TLS encryption for IPv6 communication
ip6_scan.c
Go to the documentation of this file.
1 #include "scan.h"
2 #include "ip4.h"
3 #include "ip6.h"
4 
5 /*
6  * IPv6 addresses are really ugly to parse.
7  * Syntax: (h = hex digit)
8  * 1. hhhh:hhhh:hhhh:hhhh:hhhh:hhhh:hhhh:hhhh
9  * 2. any number of 0000 may be abbreviated as "::", but only once
10  * 3. The last two words may be written as IPv4 address
11  */
12 
13 unsigned int ip6_scan(const char *s,char ip[16])
14 {
15  unsigned int i;
16  unsigned int len=0;
17  unsigned long u;
18 // const unsigned char V4mappedprefix[12] = {0,0,0,0,0,0,0,0,0,0,0xff,0xff};
19 
20  char suffix[16];
21  int prefixlen=0;
22  int suffixlen=0;
23 
24  if ((i=ip4_scan(s,ip+12))) {
25  for (len=0; len<12; ++len) ip[len]=V4mappedprefix[len];
26  return i;
27  }
28  for (i=0; i<16; i++) ip[i]=0;
29  for (;;) {
30  if (*s == ':') {
31  len++;
32  if (s[1] == ':') { /* Found "::", skip to part 2 */
33  s+=2;
34  len++;
35  break;
36  }
37  s++;
38  }
39  i = scan_xlong(s,&u);
40  if (!i) return 0;
41  if (prefixlen==12 && s[i]=='.') {
42  /* the last 4 bytes may be written as IPv4 address */
43  i=ip4_scan(s,ip+12);
44  if (i)
45  return i+len;
46  else
47  return 0;
48  }
49  ip[prefixlen++] = (u >> 8);
50  ip[prefixlen++] = (u & 255);
51  s += i; len += i;
52  if (prefixlen == 16)
53  return len;
54  }
55 
56 /* part 2, after "::" */
57  for (;;) {
58  if (*s == ':') {
59  if (suffixlen==0)
60  break;
61  s++;
62  len++;
63  } else if (suffixlen!=0)
64  break;
65  i = scan_xlong(s,&u);
66  if (!i) {
67  len--;
68  break;
69  }
70  if (suffixlen+prefixlen<=12 && s[i]=='.') {
71  int j=ip4_scan(s,suffix+suffixlen);
72  if (j) {
73  suffixlen += 4;
74  len += j;
75  break;
76  } else
77  prefixlen = 12-suffixlen; /* make end-of-loop test true */
78  }
79  suffix[suffixlen++] = (u >> 8);
80  suffix[suffixlen++] = (u & 255);
81  s += i; len += i;
82  if (prefixlen+suffixlen == 16)
83  break;
84  }
85  for (i=0; i<suffixlen; i++)
86  ip[16-suffixlen+i] = suffix[i];
87  return len;
88 }
unsigned int scan_xlong(const char *, unsigned long *)
Definition: scan_xlong.c:13
unsigned int ip6_scan(const char *s, char ip[16])
Definition: ip6_scan.c:13
unsigned int ip4_scan(const char *, char *)
const unsigned char V4mappedprefix[12]