ucspi-ssl  0.12.7
ucspi-ssl
ip6_bit.c
Go to the documentation of this file.
1 
6 #include "ip.h"
7 #include "byte.h"
8 #include "str.h"
9 #include "fmt.h"
10 #include "stralloc.h"
11 #include "ip_bit.h"
12 
13 #define BITSUBSTITUTION
14 
15 /***
16  /fn bytetohex
17  /brief Convert a number of max 255 to hex.
18  /param decimal The decimal number.
19  /param hex The converted hex value.
20 */
21 
22 void bytetohex(unsigned char decimal, char hex[3])
23 {
24  char* hexdigits = "0123456789ABCDEF";
25  int rest, number;
26  hex[0] = '0';
27  hex[1] = '0';
28  hex[2] = '\0';
29 
30  number = decimal / 16;
31  rest = decimal % 16;
32 
33  hex[0] = hexdigits[number];
34  hex[1] = hexdigits[rest];
35 }
36 
37 static char strnum[FMT_ULONG];
38 
39 /***
40  /fn ip6_bitstring
41  /brief This function converts a IPv6 address into its binary representation.
42  /param out: ip6string The destination address.
43  /param in: ip6addr The source address.
44  /param in: prefix The net prefix bits (maximum 128 bits for IPv6).
45  /return -1: lack of memory; 1: non valid IPv6 address; 0: successful converted.
46 */
47 
48 int ip6_bitstring(stralloc *ip6string, char *ip6addr, unsigned int prefix)
49 {
50  char ip6[16];
51  int bit, octettbitpos, number, shiftedvalue;
52  int i, slashpos, ip6len;
53 
54 #ifdef BITSUBSTITUTION
55  char subvalueforbitone[1];
56  subvalueforbitone[0] = 96; /* substitution starts from token '_' = 96 */
57 #endif
58 
59  ip6len = str_len(ip6addr);
60  slashpos = byte_chr(ip6addr,ip6len,'/');
61  if (!stralloc_copyb(ip6string,ip6addr,slashpos)) return -1;
62  ip6addr[slashpos] = '\0';
63 
64  if (!ip6_scan(ip6addr,ip6)) return 1;
65  if (!stralloc_copys(ip6string,"")) return -1;
66 
67  for (i = 0; i < 16; i++) {
68  number = (unsigned char) ip6[i];
69 
70  for (octettbitpos = 7; octettbitpos >= 0; octettbitpos--) {
71  shiftedvalue = 1 << octettbitpos;
72  bit = number / shiftedvalue;
73  number = number - bit * (shiftedvalue);
74 
75  if (bit) {
76 #ifdef BITSUBSTITUTION
77  if (!stralloc_catb(ip6string,subvalueforbitone,1)) return -1;
78  subvalueforbitone[0]++;
79 #else
80  if (!stralloc_cats(ip6string,"1")) return -1;
81 #endif
82  } else
83  if (!stralloc_cats(ip6string,"0")) return -1;
84 
85  prefix--;
86  if (prefix == 0) return 0;
87  }
88  }
89 
90  return 1;
91 }
92 
93 /***
94  /fn bitstring_ip6
95  /brief This function converts a bit string which is produced by ip6_bitstring()
96  into an IPv6 address. The string may start with a '^'.
97  /param in: ip6string Source string which need to be converted.
98  /param out ip6addr 0-terminated IPv6 destination address with net prefix.
99  /return -1: No memory could allocated,0: Failure,1: Success.
100 */
101 
102 int bitstring_ip6(stralloc *ip6addr ,stralloc *ip6string)
103 {
104  int j = 0;
105  int i = 0;
106  int len, prefix, shiftedvalue;
107  int bitpos = 7;
108  int decimalnumber = 0;
109  char ip6[16] = {0};
110  char ip6compact[40] = {0};
111 
112  if (!stralloc_copys(ip6addr,"")) return -1;
113  prefix = ip6string->len - 1;
114 
115  if (prefix <= 0) return 1;
116  if (prefix <= 1 || prefix > 128) return 1;
117 
118  if (ip6string->s[0] == '^') j = 1;
119 
120  for (i = j, j = 0; i <= prefix; i++) {
121  if (ip6string->s[i] != '0') {
122  shiftedvalue = 1 << bitpos;
123  decimalnumber += shiftedvalue;
124  }
125  bitpos--;
126  if (bitpos == -1) { /* Put each converted byte into the array. */
127  if (j < 16) {
128  ip6[j] = (unsigned char) decimalnumber;
129  j++;
130  bitpos = 7;
131  decimalnumber = 0;
132  }
133  }
134  }
135 
136  if (bitpos < 7) { /* Last bit was read,but the number was not converted. */
137  ip6[j] = (unsigned char) decimalnumber;
138  j++;
139  }
140 
141  len = ip6_fmt(ip6compact,ip6);
142  if (!len) return 1;
143 
144  if (!stralloc_copyb(ip6addr,ip6compact,len)) return -1;
145  if (!stralloc_cats(ip6addr,"/")) return -1;
146  if (!stralloc_catb(ip6addr,strnum,fmt_ulong(strnum,prefix))) return -1;
147  if (!stralloc_0(ip6addr)) return -1;
148 
149  return 0;
150 }
151 /***
152  /fn ip6_fmt_str
153  /brief This function expands any valid IPv6 address into its full format of 16 bytes.
154  It returns the number of processed tokens on success.
155  /param src Source IPv6 address.
156  /param destination Expanded IPv6 address.
157  /return -1: No memory could allocated; 1: failure, 0: success
158 */
159 
160 unsigned int ip6_fmt_str(stralloc *dest, char *src)
161 {
162  stralloc addr = {0};
163  char ip6[16];
164  char hexvalue[3] = {0, 0, 0};
165  int i;
166 
167  if (!stralloc_copys(&addr,src)) return -1;
168  if (!stralloc_0(&addr)) return -1;
169 
170  if (ip6_scan(addr.s,ip6) == 0) return 1;
171  if (!stralloc_copys(dest,"")) return -1;
172 
173  for (i = 0; i < 16; i++) {
174  bytetohex((unsigned char)ip6[i],hexvalue);
175  stralloc_catb(dest,hexvalue,2);
176  if (!((i+1) % 2) && (i+1) < 16)
177  if (!stralloc_cats(dest,":")) return -1; /*Append ':' after every two bytes.*/
178  }
179  return 0;
180 }
int bitstring_ip6(stralloc *ip6addr, stralloc *ip6string)
Definition: ip6_bit.c:102
void bytetohex(unsigned char decimal, char hex[3])
Definition: ip6_bit.c:22
int ip6_bitstring(stralloc *ip6string, char *ip6addr, unsigned int prefix)
Definition: ip6_bit.c:48
unsigned int ip6_fmt_str(stralloc *dest, char *src)
Definition: ip6_bit.c:160