@@ -40,6 +40,26 @@ IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_oc
4040 _address.bytes [15 ] = fourth_octet;
4141}
4242
43+ IPAddress::IPAddress (uint8_t o1, uint8_t o2, uint8_t o3, uint8_t o4, uint8_t o5, uint8_t o6, uint8_t o7, uint8_t o8, uint8_t o9, uint8_t o10, uint8_t o11, uint8_t o12, uint8_t o13, uint8_t o14, uint8_t o15, uint8_t o16) {
44+ _type = IPv6;
45+ _address.bytes [0 ] = o1;
46+ _address.bytes [1 ] = o2;
47+ _address.bytes [2 ] = o3;
48+ _address.bytes [3 ] = o4;
49+ _address.bytes [4 ] = o5;
50+ _address.bytes [5 ] = o6;
51+ _address.bytes [6 ] = o7;
52+ _address.bytes [7 ] = o8;
53+ _address.bytes [8 ] = o9;
54+ _address.bytes [9 ] = o10;
55+ _address.bytes [10 ] = o11;
56+ _address.bytes [11 ] = o12;
57+ _address.bytes [12 ] = o13;
58+ _address.bytes [13 ] = o14;
59+ _address.bytes [14 ] = o15;
60+ _address.bytes [15 ] = o16;
61+ }
62+
4363IPAddress::IPAddress (uint32_t address)
4464{
4565 // IPv4 only
@@ -135,7 +155,7 @@ bool IPAddress::fromString6(const char *address) {
135155 while (*address)
136156 {
137157 char c = tolower (*address++);
138- if (isalnum (c)) {
158+ if (isalnum (c) && c <= ' f ' ) {
139159 if (c >= ' a' )
140160 c -= ' a' - ' 0' - 10 ;
141161 acc = acc * 16 + (c - ' 0' );
@@ -145,18 +165,26 @@ bool IPAddress::fromString6(const char *address) {
145165 }
146166 else if (c == ' :' ) {
147167 if (*address == ' :' ) {
148- if (doubledots >= 0 )
168+ if (doubledots >= 0 ) {
149169 // :: allowed once
150170 return false ;
171+ }
172+ if (*address != ' \0 ' && *(address + 1 ) == ' :' ) {
173+ // ::: not allowed
174+ return false ;
175+ }
151176 // remember location
152177 doubledots = dots + !!acc;
153178 address++;
179+ } else if (*address == ' \0 ' ) {
180+ // can't end with a single colon
181+ return false ;
154182 }
155183 if (dots == 7 )
156184 // too many separators
157185 return false ;
158- _address.bytes [dots] = acc >> 2 ;
159- _address.bytes [dots + 1 ] = acc & 0xff ;
186+ _address.bytes [dots * 2 ] = acc >> 8 ;
187+ _address.bytes [dots * 2 + 1 ] = acc & 0xff ;
160188 dots++;
161189 acc = 0 ;
162190 }
@@ -165,11 +193,16 @@ bool IPAddress::fromString6(const char *address) {
165193 return false ;
166194 }
167195
168- if (doubledots == -1 && dots != 7 )
196+ if (doubledots == -1 && dots != 7 ) {
169197 // Too few separators
170198 return false ;
171- _address.bytes [dots] = acc >> 2 ;
172- _address.bytes [dots + 1 ] = acc & 0xff ;
199+ }
200+ if (doubledots > -1 && dots > 6 ) {
201+ // Too many segments
202+ return false ;
203+ }
204+ _address.bytes [dots * 2 ] = acc >> 8 ;
205+ _address.bytes [dots * 2 + 1 ] = acc & 0xff ;
173206 dots++;
174207
175208 if (doubledots != -1 ) {
@@ -235,16 +268,16 @@ size_t IPAddress::printTo(Print& p) const
235268 size_t n = 0 ;
236269
237270 if (_type == IPv6) {
238- // IPv6 IETF canonical format: left-most longest run of all zero fields, lower case
271+ // IPv6 IETF canonical format: compress left-most longest run of two or more zero fields, lower case
239272 int8_t longest_start = -1 ;
240- int8_t longest_length = 0 ;
273+ int8_t longest_length = 1 ;
241274 int8_t current_start = -1 ;
242275 int8_t current_length = 0 ;
243276 for (int8_t f = 0 ; f < 8 ; f++) {
244277 if (_address.bytes [f * 2 ] == 0 && _address.bytes [f * 2 + 1 ] == 0 ) {
245278 if (current_start == -1 ) {
246279 current_start = f;
247- current_length = 0 ;
280+ current_length = 1 ;
248281 } else {
249282 current_length++;
250283 }
@@ -258,24 +291,27 @@ size_t IPAddress::printTo(Print& p) const
258291 }
259292 for (int f = 0 ; f < 8 ; f++) {
260293 if (f < longest_start || f >= longest_start + longest_length) {
261- uint8_t c1 = _address.bytes [f * 2 ] >> 1 ;
294+ uint8_t c1 = _address.bytes [f * 2 ] >> 4 ;
262295 uint8_t c2 = _address.bytes [f * 2 ] & 0xf ;
263- uint8_t c3 = _address.bytes [f * 2 + 1 ] >> 1 ;
296+ uint8_t c3 = _address.bytes [f * 2 + 1 ] >> 4 ;
264297 uint8_t c4 = _address.bytes [f * 2 + 1 ] & 0xf ;
265298 if (c1 > 0 ) {
266- n += p.print (c1 < 10 ? ' 0' + c1 : ' a' + c1 - 10 );
299+ n += p.print (( char )( c1 < 10 ? ' 0' + c1 : ' a' + c1 - 10 ) );
267300 }
268301 if (c1 > 0 || c2 > 0 ) {
269- n += p.print (c2 < 10 ? ' 0' + c2 : ' a' + c2 - 10 );
302+ n += p.print (( char )( c2 < 10 ? ' 0' + c2 : ' a' + c2 - 10 ) );
270303 }
271304 if (c1 > 0 || c2 > 0 || c3 > 0 ) {
272- n += p.print (c3 < 10 ? ' 0' + c3 : ' a' + c3 - 10 );
305+ n += p.print (( char )( c3 < 10 ? ' 0' + c3 : ' a' + c3 - 10 ) );
273306 }
274- n += p.print (c4 < 10 ? ' 0' + c4 : ' a' + c4 - 10 );
307+ n += p.print (( char )( c4 < 10 ? ' 0' + c4 : ' a' + c4 - 10 ) );
275308 if (f < 7 ) {
276309 n += p.print (' :' );
277310 }
278311 } else if (f == longest_start) {
312+ if (longest_start == 0 ) {
313+ n += p.print (' :' );
314+ }
279315 n += p.print (' :' );
280316 }
281317 }
0 commit comments