1 /*
2   Copyright 2020 Northern.tech AS
3 
4   This file is part of CFEngine 3 - written and maintained by Northern.tech AS.
5 
6   This program is free software; you can redistribute it and/or modify it
7   under the terms of the GNU General Public License as published by the
8   Free Software Foundation; version 3.
9 
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14 
15   You should have received a copy of the GNU General Public License
16   along with this program; if not, write to the Free Software
17   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
18 
19   To the extent this program is licensed as part of the Enterprise
20   versions of CFEngine, the applicable Commercial Open Source License
21   (COSL) may apply to this file if you as a licensee so wish it. See
22   included file COSL.txt.
23 */
24 
25 #include <platform.h>
26 
27 #include <stdint.h>
28 #include <ctype.h>
29 #include <ip_address.h>
30 #include <alloc.h>
31 
32 struct IPV4Address {
33     uint8_t octets[4];
34     uint16_t port;
35 };
36 struct IPV6Address {
37     uint16_t sixteen[8];
38     uint16_t port;
39 };
40 
41 struct IPAddress {
42     void *address;
43     int type;
44 };
45 
46 #define Char2Dec(o, c) \
47     (o * 10) + c - '0'
48 
49 /*
50  * Hexadecimal conversion is not as simple as decimal conversion,
51  * so we implement it here.
52  * We do not check for errors, we assume the caller has checked that
53  * the characters are hexadecimal.
54  */
Char2Hex(int beginning,char increment)55 static int Char2Hex(int beginning, char increment)
56 {
57     int number = beginning;
58     number *= 16;
59     if (('a' <= increment) && (increment <= 'f'))
60     {
61         number += (increment - 'a' + 0x0A);
62     }
63     else if (('A' <= increment) && (increment <= 'F'))
64     {
65         number += (increment - 'A' + 0x0A);
66     }
67     else
68     {
69         number += (increment - '0');
70     }
71     return number;
72 }
73 
74 /*
75  * This function parses the source pointer and checks if it conforms to the
76  * 0a0b0c0d or 0a0b0c0d:0e0f formats (commonly used in procfs)
77  *
78  * If address is not NULL and the address is IPV4, then the result is copied there.
79  *
80  * Returns 0 on success.
81  */
IPV4_hex_parser(const char * source,struct IPV4Address * address)82 static int IPV4_hex_parser(const char *source, struct IPV4Address *address)
83 {
84     {
85         // shortcut for the 0a0b0c0d format
86         unsigned int a, b, c, d, pport = 0;
87         if (strlen(source) == 8 &&
88             sscanf(source, "%2x%2x%2x%2x", &a, &b, &c, &d) == 4)
89         {
90             address->octets[3] = a;
91             address->octets[2] = b;
92             address->octets[1] = c;
93             address->octets[0] = d;
94             address->port = pport;
95             return 0;
96         }
97 
98         // shortcut for the 0a0b0c0d:0e0f format
99         if (strlen(source) == 8+1+4 &&
100             sscanf(source, "%2x%2x%2x%2x:%4x", &a, &b, &c, &d, &pport) == 5)
101         {
102             address->octets[3] = a;
103             address->octets[2] = b;
104             address->octets[1] = c;
105             address->octets[0] = d;
106             address->port = pport;
107             return 0;
108         }
109     }
110 
111     return -1;
112 }
113 
114 /*
115  * This function parses the source pointer and checks if it conforms to the
116  * RFC 791.
117  *
118  * xxx.xxx.xxx.xxx[:ppppp]
119  *
120  * If address is not NULL and the address is IPV4, then the result is copied there.
121  *
122  * Returns 0 on success.
123  */
IPV4_parser(const char * source,struct IPV4Address * address)124 static int IPV4_parser(const char *source, struct IPV4Address *address)
125 {
126     char *p = NULL;
127     int octet = 0;
128     int port = 0;
129     int period_counter = 0;
130     int port_counter = 0;
131     int char_counter = 0;
132     bool is_period = false;
133     bool is_digit = false;
134     bool is_port = false;
135     bool has_digit = false;
136 
137     /*
138      * For simplicity sake we initialize address (if not NULL).
139      */
140     if (address)
141     {
142         int i = 0;
143         for (i = 0; i < 4; ++i)
144         {
145             address->octets[i] = 0;
146         }
147         address->port = 0;
148     }
149 
150     /*
151      * IPV4 parsing has 6 states, of which:
152      * 2 are end states
153      * 4 are parsing states
154      *
155      * States 0 to 3 are purely address parsing. State 5
156      * might never be reached if there is no port.
157      * State 4 is the final state if everything went ok.
158      * State 6 is reached in case of error.
159      *
160      * 0    1    2    3
161      * |d   |d   |d   |d
162      * | p  | p  | p  | done
163      * 0 -> 1 -> 2 -> 3 ->  4
164      * |    |    |    |     |
165      * 7 <--+----+----+     |
166      *     error      | ':' |
167      *               _5-----+
168      *             d \| done
169      */
170     int state = 0;
171     bool state_change = false;
172     for (p = (char *)source; *p != '\0'; ++p)
173     {
174         /*
175          * Do some character recognition
176          */
177         is_digit = isdigit(*p);
178         is_period = (*p == '.') ? 1 : 0;
179         is_port = (*p == ':') ? 1 : 0;
180         /*
181          * Update the corresponding flags.
182          */
183         if (is_period)
184         {
185             period_counter++;
186         }
187         if (is_port)
188         {
189             port_counter++;
190         }
191         /*
192          * Do the right operation depending on the state
193          */
194         switch (state)
195         {
196         case 0:
197         case 1:
198         case 2:
199             /*
200              * The three first states are the same.
201              * XXX.XXX.XXX.xxx[:nnnnn]
202              */
203             if (is_digit)
204             {
205                 octet = Char2Dec(octet, *p);
206                 has_digit = true;
207             }
208             else if (is_period)
209             {
210                 if (address)
211                 {
212                     address->octets[state] = octet;
213                 }
214                 state++;
215                 state_change = true;
216             }
217             else
218             {
219                 state = 7;
220                 state_change = true;
221             }
222             break;
223         case 3:
224             /*
225              * This case is different from the previous ones. A period here means error.
226              * xxx.xxx.xxx.XXX[:nnnnn]
227              */
228             if (is_digit)
229             {
230                 octet = Char2Dec(octet, *p);
231                 has_digit = true;
232             }
233             else if (is_port)
234             {
235                 if (address)
236                 {
237                     address->octets[state] = octet;
238                 }
239                 state = 5;
240                 state_change = true;
241             }
242             else
243             {
244                 state = 7;
245                 state_change = true;
246             }
247             break;
248         case 4:
249             break;
250         case 5:
251             if (is_digit)
252             {
253                 port = Char2Dec(port, *p);
254             }
255             else
256             {
257                 state = 7;
258                 state_change = true;
259             }
260             break;
261         case 6:
262         default:
263             return -1;
264             break;
265         }
266         /*
267          * It is important to the filtering before counting the characters.
268          * Otherwise the counter will need to start from -1.
269          */
270         char_counter++;
271         /*
272          * Do some sanity checks, this should hold no matter
273          * in which state of the state machine we are.
274          */
275         if (octet > 255)
276         {
277             return -1;
278         }
279         if (port > 65535)
280         {
281             return -1;
282         }
283         if (period_counter > 1)
284         {
285             return -1;
286         }
287         if (port_counter > 1)
288         {
289             return -1;
290         }
291         if (state_change)
292         {
293             /*
294              * Check that we have digits, otherwise the transition is wrong.
295              */
296             if (!has_digit)
297             {
298                 return -1;
299             }
300             /*
301              * Reset all the variables.
302              */
303             char_counter = 0;
304             octet = 0;
305             port = 0;
306             period_counter = 0;
307             port_counter = 0;
308             is_period = false;
309             is_digit = false;
310             is_port = false;
311             has_digit = false;
312             state_change = false;
313         }
314     }
315     /*
316      * These states are not end state, which mean we exited the loop because of an error
317      */
318     if ((state == 0) || (state == 1) || (state == 2))
319     {
320         return -1;
321     }
322     /*
323      * If state is 3 then we exited the loop without copying the last octet.
324      * This is because we didn't get to state 4.
325      * Notice that we need to check if we had characters, it might be possible that we
326      * have the following situation 'xxx.xxx.xxx.' which will fit the state change but not
327      * produce a valid IP.
328      */
329     if (state == 3)
330     {
331         if (char_counter == 0)
332         {
333             return -1;
334         }
335         if (address)
336         {
337             address->octets[3] = octet;
338         }
339     }
340     /*
341      * If state is 5 then we exited the loop without copying the port.
342      * This is because we hit a '\0'.
343      * Notice that we need to check if we had characters, it might be possible that we
344      * have the following situation 'xxx.xxx.xxx.xxx:' which will fit the state change but not
345      * produce a valid IP.
346      */
347     if (state == 5)
348     {
349         if (char_counter == 0)
350         {
351             return -1;
352         }
353         if (address)
354         {
355             address->port = port;
356         }
357     }
358     /*
359      * If state is 6 then there was an error.
360      */
361     if (state == 6)
362     {
363         return -1;
364     }
365     return 0;
366 }
367 
368 /*
369  * This function parses the address and checks if it conforms to the
370  * 0a0b0c0d0e0f0g0h or 0a0b0c0d0e0f0g0h:0i0j format (commonly used in procfs)
371  *
372  * Returns 0 on success.
373  */
IPV6_hex_parser(const char * source,struct IPV6Address * address)374 static int IPV6_hex_parser(const char *source, struct IPV6Address *address)
375 {
376     {
377         // shortcut for the 0a0b0c0d0e0f0g0h format
378         unsigned int a, b, c, d, e, f, g, h, pport = 0;
379 
380         if (strlen(source) == 32 &&
381             sscanf(source, "%4x%4x%4x%4x%4x%4x%4x%4x", &a, &b, &c, &d, &e, &f, &g, &h) == 8)
382         {
383             address->sixteen[0] = a;
384             address->sixteen[1] = b;
385             address->sixteen[2] = c;
386             address->sixteen[3] = d;
387             address->sixteen[4] = e;
388             address->sixteen[5] = f;
389             address->sixteen[6] = g;
390             address->sixteen[7] = h;
391             return 0;
392         }
393 
394         if (strlen(source) == 32+1+4 &&
395             sscanf(source, "%4x%4x%4x%4x%4x%4x%4x%4x:%4x", &a, &b, &c, &d, &e, &f, &g, &h, &pport) == 9)
396         {
397             address->sixteen[0] = a;
398             address->sixteen[1] = b;
399             address->sixteen[2] = c;
400             address->sixteen[3] = d;
401             address->sixteen[4] = e;
402             address->sixteen[5] = f;
403             address->sixteen[6] = g;
404             address->sixteen[7] = h;
405             address->port = pport;
406             return 0;
407         }
408     }
409 
410     return -1;
411 }
412 
413 /*
414  * This function parses the address and checks if it conforms to the
415  * RFCs 2373, 2460 and 5952.
416  * We do not support Microsoft UNC encoding, i.e.
417  * hhhh-hhhh-hhhh-hhhh-hhhh-hhhh-hhhh-hhhh.ipv6-literal.net
418  * Despite following RFC 5292 we do not signal errors derived from bad
419  * zero compression although this might change on time, so please do not
420  * trust that we will honor address with wrong zero compression.
421  *
422  * Returns 0 on success.
423  */
IPV6_parser(const char * source,struct IPV6Address * address)424 static int IPV6_parser(const char *source, struct IPV6Address *address)
425 {
426     /*
427      * IPV6 parsing is more complex than IPV4 parsing. There are a few ground rules:
428      * - Leading zeros can be omitted.
429      * - Fields that are just zeros can be abbreviated to one zero or completely omitted.
430      * In the later case the following notation is used: '::'.
431      * - Port number is specified in a special way:
432      * [hhhh:hhhh:hhhh:hhhh:hhhh:hhhh:hhhh:hhhh]:ppppp
433      * Notice that it is possible to have the '[' and ']' without specifying a port.
434      *
435      * Simplified state machine:
436      *
437      * _h      _h      _h      _h      _h      _h      _h      _h              _d
438      * |/ ':'  |/ ':'  |/ ':'  |/ ':'  |/ ':'  |/ ':'  |/ ':'  |/ ']'    ':'   |/ done
439      * 0------>1------>2------>3------>4------>5------>6------>7------>8------>9------>11
440      * |\                                                      | done  |
441      * -'['                                                    9<------+
442      *
443      * This is a simplified state machine since I assume that we keep the square brackets inside
444      * the same state as hexadecimal digits, which in practice is not true.
445      */
446     char *p = NULL;
447     int sixteen = 0;
448     int unsorted_sixteen[6];
449     int unsorted_pointer = 0;
450     int bracket_expected = 0;
451     int port = 0;
452     int char_counter = 0;
453     bool is_start_bracket = 0;
454     bool is_end_bracket = 0;
455     bool is_colon = 0;
456     bool is_hexdigit = 0;
457     bool is_upper_hexdigit = 0;
458     bool is_digit = 0;
459     int zero_compression = 0;
460     int already_compressed = 0;
461     int state = 0;
462     bool state_change = false;
463 
464     /*
465      * Initialize our container for unknown numbers.
466      */
467     for (unsorted_pointer = 0; unsorted_pointer < 6; ++unsorted_pointer)
468     {
469         unsorted_sixteen[unsorted_pointer] = 0;
470     }
471     unsorted_pointer = 0;
472     /*
473      * For simplicity sake we initialize address (if not NULL).
474      */
475     if (address)
476     {
477         int i = 0;
478         for (i = 0; i < 8; ++i)
479         {
480             address->sixteen[i] = 0;
481         }
482         address->port = 0;
483     }
484 
485     for (p = (char *)source; *p != '\0'; ++p)
486     {
487         /*
488          * Take a closer look at the character
489          */
490         is_start_bracket = (*p == '[') ? 1 : 0;
491         is_end_bracket = (*p == ']') ? 1 : 0;
492         is_hexdigit = isxdigit(*p);
493         is_digit = isdigit(*p);
494         is_colon = (*p == ':') ? 1 : 0;
495         if (is_hexdigit)
496         {
497             if (isalpha(*p))
498             {
499                 is_upper_hexdigit = isupper(*p);
500             }
501         }
502 
503         switch (state)
504         {
505         case 0:
506             /*
507              * This case is slightly different because of the possible presence of '['.
508              * Notice that '[' is only valid as the first character, anything else is
509              * an error!
510              */
511             if (is_start_bracket)
512             {
513                 if (char_counter == 0)
514                 {
515                     bracket_expected = 1;
516                 }
517                 else
518                 {
519                     state = 11;
520                     state_change = true;
521                 }
522             }
523             else if (is_hexdigit)
524             {
525                 /*
526                  * RFC 5952 forbids upper case hex digits
527                  */
528                 if (is_upper_hexdigit)
529                 {
530                     state = 11;
531                     state_change = true;
532                 }
533                 else
534                 {
535                     sixteen = Char2Hex(sixteen, *p);
536                 }
537             }
538             else if (is_colon)
539             {
540                 if (address)
541                 {
542                     address->sixteen[0] = sixteen;
543                 }
544                 state = 1;
545                 state_change = true;
546             }
547             else
548             {
549                 state = 11;
550                 state_change = true;
551             }
552             break;
553         case 1:
554             /*
555              * This state is special since it cannot have a ']' as in the next
556              * states.
557              */
558             if (is_hexdigit)
559             {
560                 /*
561                  * RFC 5952 forbids upper case hex digits
562                  */
563                 if (is_upper_hexdigit)
564                 {
565                     state = 11;
566                     state_change = true;
567                 }
568                 else
569                 {
570                     sixteen = Char2Hex(sixteen, *p);
571                 }
572             }
573             else if (is_colon)
574             {
575                 if (char_counter == 0)
576                 {
577                     /*
578                      * This means 'X::Y...' which means zero compression.
579                      * Flag it!
580                      */
581                     zero_compression = 1;
582                     already_compressed = 1;
583                 }
584                 else
585                 {
586                     if (address)
587                     {
588                         address->sixteen[state] = sixteen;
589                     }
590                 }
591                 ++state;
592                 state_change = true;
593             }
594             else
595             {
596                 state = 11;
597                 state_change = true;
598             }
599             break;
600         case 2:
601         case 3:
602         case 4:
603         case 5:
604         case 6:
605             if (is_hexdigit)
606             {
607                 /*
608                  * RFC 5952 forbids upper case hex digits
609                  */
610                 if (is_upper_hexdigit)
611                 {
612                     state = 11;
613                     state_change = true;
614                 }
615                 else
616                 {
617                     sixteen = Char2Hex(sixteen, *p);
618                 }
619             }
620             else if (is_colon)
621             {
622                 if (char_counter == 0)
623                 {
624                     if (already_compressed)
625                     {
626                         /*
627                          * The '::' symbol can only occur once in a given address.
628                          */
629                         state = 11;
630                         state_change = true;
631                     }
632                     else
633                     {
634                         /*
635                          * This means '...:X::Y...' which means zero compression.
636                          * Flag it!
637                          */
638                         zero_compression = 1;
639                         already_compressed = 1;
640                     }
641                 }
642                 else
643                 {
644                     if (zero_compression)
645                     {
646                         /*
647                          * If zero compression is enabled, then we cannot trust the position
648                          * since we might compressed several fields. We store the value and
649                          * look at them afterwards.
650                          */
651                         unsorted_sixteen[unsorted_pointer] = sixteen;
652                         ++unsorted_pointer;
653                     }
654                     else
655                     {
656                         /*
657                          * No zero compression, just assign the address and keep moving.
658                          */
659                         if (address)
660                         {
661                             address->sixteen[state] = sixteen;
662                         }
663                     }
664                     ++state;
665                     state_change = true;
666                 }
667             }
668             else if (is_end_bracket)
669             {
670                 if (bracket_expected && zero_compression)
671                 {
672                     bracket_expected = 0;
673                     /*
674                      * RFC 5952 says that we can end an address at any point after
675                      * the second position (consequence of the zero compression).
676                      * Therefore if we find a ']' we just jump to state 8.
677                      */
678                     unsorted_sixteen[unsorted_pointer] = sixteen;
679                     ++unsorted_pointer;
680                     state = 8;
681                     state_change = true;
682                 }
683                 else
684                 {
685                     /*
686                      * Funny stuff, we got a ']' that we were not expecting.
687                      * Politely walk back and signal the error.
688                      */
689                     state = 11;
690                     state_change = true;
691                 }
692             }
693             else
694             {
695                 state = 11;
696                 state_change = true;
697             }
698             break;
699         case 7:
700             /*
701              * This case is special.
702              */
703             if (is_hexdigit)
704             {
705                 /*
706                  * RFC 5952 forbids uppercase hex digits
707                  */
708                 if (is_upper_hexdigit)
709                 {
710                     state = 11;
711                     state_change = true;
712                 }
713                 else
714                 {
715                     sixteen = Char2Hex(sixteen, *p);
716                 }
717             }
718             else if (is_end_bracket)
719             {
720                 if (bracket_expected)
721                 {
722                     bracket_expected = 0;
723                     if (address)
724                     {
725                         address->sixteen[state] = sixteen;
726                     }
727                     /*
728                      * The last possible position for a sixteen is number 8.
729                      */
730                     ++state;
731                     state_change = true;
732                 }
733                 else
734                 {
735                     /*
736                      * Funny stuff, we got a ']' that we were not expecting.
737                      * Politely walk back and signal the error.
738                      */
739                     state = 11;
740                     state_change = true;
741                 }
742             }
743             else
744             {
745                 state = 11;
746                 state_change = true;
747             }
748             break;
749         case 8:
750             if (is_colon)
751             {
752                 ++state;
753                 state_change = true;
754             }
755             else
756             {
757                 state = 11;
758                 state_change = true;
759             }
760             break;
761         case 9:
762             if (is_digit)
763             {
764                 port = Char2Dec(port, *p);
765             }
766             else
767             {
768                 state = 11;
769                 state_change = true;
770             }
771             break;
772         case 10:
773             break;
774         case 11:
775         default:
776             return -1;
777             break;
778         }
779         char_counter++;
780         if (sixteen > 0xFFFF)
781         {
782             return -1;
783         }
784         if (port > 65535)
785         {
786             return -1;
787         }
788         if (state_change)
789         {
790             sixteen = 0;
791             port = 0;
792             char_counter = 0;
793             is_start_bracket = false;
794             is_end_bracket = false;
795             is_colon = false;
796             is_hexdigit = false;
797             is_upper_hexdigit = false;
798             is_digit = 0;
799             state_change = false;
800         }
801     }
802     /*
803      * Look at the end state and return accordingly.
804      */
805     if ((state == 0) || (state == 1))
806     {
807         /*
808          * These states are not final states, so if we exited is because something went wrong.
809          */
810         return -1;
811     }
812     /*
813      * Thanks to RFC5952 the final states can be intermediate states. This because of zero compression,
814      * which means that the following address 1:0:0:0:0:0:0:1 can be written as
815      * 1::1. Not to mention more exotic varieties such as 1:0:0:0:0:0:0:0 1:: or
816      * 0:0:0:0:0:0:0:0 ::
817      * The first intermediate state that can exit is 2, since even the smallest of all address('::')
818      * will have at least two ':'.
819      * Another exotic case is 'X:0:0:Y:0:0:0:Z' which becomes 'X::Y:0:0:0:Z' or X:0:0:Y::Z because the symbol '::'
820      * can appear only once in a given address.
821      */
822     if ((state == 2) || (state == 3) || (state == 4) || (state == 5) || (state == 6))
823     {
824         /*
825          * We check first for non-closed brackets.
826          * Then we check if there is a number that has not been added to our array.
827          * Finally we move to zero compression.
828          */
829         if (bracket_expected)
830         {
831             return -1;
832         }
833         unsorted_sixteen[unsorted_pointer] = sixteen;
834         ++unsorted_pointer;
835         if (zero_compression)
836         {
837             /*
838              * If there is no address, then we can just return :-)
839              */
840             if (address)
841             {
842                 /*
843                  * We need to find the rightful positions for those numbers.
844                  * We use a simple trick:
845                  * We know how many unsorted addresses we have from unsorted pointer,
846                  * and we know that once zero_compression is activated we do not fill
847                  * any more numbers to the address structure. Therefore the right way
848                  * to do this is to take the array of unsorted_sixteen and start assigning
849                  * numbers backwards.
850                  */
851                 int i = 0;
852                 for (i = 0; i < unsorted_pointer; ++i)
853                 {
854                     address->sixteen[7 - i] = unsorted_sixteen[unsorted_pointer - i - 1];
855                 }
856             }
857         }
858         else
859         {
860             /*
861              * We cannot end up here without zero compression, or an error.
862              */
863             return -1;
864         }
865     }
866     if (state == 7)
867     {
868         /*
869          * This state corresponds to the final state of a simple ipv6 address, i.e.
870          * xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx
871          * We exited because we ran out of characters. Let's check that we have something
872          * before assigning things.
873          */
874         if (char_counter == 0)
875         {
876             /*
877              * The last field was empty, signal the error.
878              */
879             return -1;
880         }
881         if (bracket_expected)
882         {
883             /*
884              * We were expecting a bracket but it never came, so this is an error.
885              */
886             return -1;
887         }
888         if (address)
889         {
890             address->sixteen[7] = sixteen;
891         }
892     }
893     if (state == 8)
894     {
895         /*
896          * This state corresponds to the final state if brackets were present.
897          * We still need to check if zero compression was activated and copy
898          * the values if so.
899          */
900         if (zero_compression)
901         {
902             /*
903              * If there is no address, then we can just return :-)
904              */
905             if (address)
906             {
907                 /*
908                  * We need to find the rightful positions for those numbers.
909                  * We use a simple trick:
910                  * We know how many unsorted addresses we have from unsorted pointer,
911                  * and we know that once zero_compression is activated we do not fill
912                  * any more numbers to the address structure. Therefore the right way
913                  * to do this is to take the array of unsorted_sixteen and start assigning
914                  * numbers backwards.
915                  */
916                 int i = 0;
917                 for (i = 0; i < unsorted_pointer; ++i)
918                 {
919                     address->sixteen[7 - i] = unsorted_sixteen[i];
920                 }
921             }
922         }
923     }
924     if (state == 9)
925     {
926         /*
927          * This state corresponds to the final state if we had brackets around us.
928          * This is usually used to append a port number to the address, so we check
929          * if we have a port and then assign it.
930          */
931         if (char_counter == 0)
932         {
933             /*
934              * The last field was empty, signal the error.
935              */
936             return -1;
937         }
938         if (address)
939         {
940             address->port = port;
941         }
942     }
943     if (state == 11)
944     {
945         /*
946          * Error state
947          */
948         return -1;
949     }
950     return 0;
951 }
952 
IPAddressNew(Buffer * source)953 IPAddress *IPAddressNew(Buffer *source)
954 {
955     if (!source || !BufferData(source))
956     {
957         return NULL;
958     }
959     IPAddress *address = NULL;
960     const char *pad = BufferData(source);
961     struct IPV4Address *ipv4 = NULL;
962     struct IPV6Address *ipv6 = NULL;
963     ipv4 = (struct IPV4Address *)xmalloc(sizeof(struct IPV4Address));
964     ipv6 = (struct IPV6Address *)xmalloc(sizeof(struct IPV6Address));
965 
966     if (IPV4_parser(pad, ipv4) == 0)
967     {
968         free (ipv6);
969         address = (IPAddress *)xmalloc(sizeof(IPAddress));
970         address->type = IP_ADDRESS_TYPE_IPV4;
971         address->address = (void *)ipv4;
972     }
973     else if (IPV6_parser(pad, ipv6) == 0)
974     {
975         free (ipv4);
976         address = (IPAddress *)xmalloc(sizeof(IPAddress));
977         address->type = IP_ADDRESS_TYPE_IPV6;
978         address->address = (void *)ipv6;
979     }
980     else
981     {
982         /*
983          * It was not a valid IP address.
984          */
985         free (ipv4);
986         free (ipv6);
987         return NULL;
988     }
989     return address;
990 }
991 
IPAddressNewHex(Buffer * source)992 IPAddress *IPAddressNewHex(Buffer *source)
993 {
994     if (!source || !BufferData(source))
995     {
996         return NULL;
997     }
998     IPAddress *address = NULL;
999     const char *pad = BufferData(source);
1000     struct IPV4Address *ipv4 = NULL;
1001     struct IPV6Address *ipv6 = NULL;
1002     ipv4 = (struct IPV4Address *)xmalloc(sizeof(struct IPV4Address));
1003     ipv6 = (struct IPV6Address *)xmalloc(sizeof(struct IPV6Address));
1004 
1005     if (IPV4_hex_parser(pad, ipv4) == 0)
1006     {
1007         free (ipv6);
1008         address = (IPAddress *)xmalloc(sizeof(IPAddress));
1009         address->type = IP_ADDRESS_TYPE_IPV4;
1010         address->address = (void *)ipv4;
1011     }
1012     else if (IPV6_hex_parser(pad, ipv6) == 0)
1013     {
1014         free (ipv4);
1015         address = (IPAddress *)xmalloc(sizeof(IPAddress));
1016         address->type = IP_ADDRESS_TYPE_IPV6;
1017         address->address = (void *)ipv6;
1018     }
1019     else
1020     {
1021         /*
1022          * It was not a valid IP address.
1023          */
1024         free (ipv4);
1025         free (ipv6);
1026         return NULL;
1027     }
1028     return address;
1029 }
1030 
IPAddressDestroy(IPAddress ** address)1031 int IPAddressDestroy(IPAddress **address)
1032 {
1033     if (!address || !(*address))
1034     {
1035         return 0;
1036     }
1037     if ((*address)->address)
1038     {
1039         free ((*address)->address);
1040     }
1041     free (*address);
1042     *address = NULL;
1043     return 0;
1044 }
1045 
IPAddressType(IPAddress * address)1046 int IPAddressType(IPAddress *address)
1047 {
1048     if (!address)
1049     {
1050         return -1;
1051     }
1052     return address->type;
1053 }
1054 
IPAddressGetAddress(IPAddress * address)1055 Buffer *IPAddressGetAddress(IPAddress *address)
1056 {
1057     if (!address)
1058     {
1059         return NULL;
1060     }
1061     Buffer *buffer = NULL;
1062     int result = 0;
1063 
1064     if (address->type == IP_ADDRESS_TYPE_IPV4)
1065     {
1066         struct IPV4Address *ipv4 = (struct IPV4Address *)address->address;
1067         buffer = BufferNew();
1068 #if BIG_ENDIAN
1069         result = BufferPrintf(buffer, "%u.%u.%u.%u", ipv4->octets[0], ipv4->octets[1], ipv4->octets[2], ipv4->octets[3]);
1070 #elif LITTLE_ENDIAN
1071         result = BufferPrintf(buffer, "%u.%u.%u.%u", ipv4->octets[3], ipv4->octets[2], ipv4->octets[1], ipv4->octets[0]);
1072 #else
1073 #warning "Unrecognized endianness, assuming big endian"
1074         result = BufferPrintf(buffer, "%u.%u.%u.%u", ipv4->octets[0], ipv4->octets[1], ipv4->octets[2], ipv4->octets[3]);
1075 #endif
1076     }
1077     else if (address->type == IP_ADDRESS_TYPE_IPV6)
1078     {
1079         struct IPV6Address *ipv6 = (struct IPV6Address *)address->address;
1080         buffer = BufferNew();
1081 #if BIG_ENDIAN
1082         result = BufferPrintf(buffer, "%x:%x:%x:%x:%x:%x:%x:%x", ipv6->sixteen[0], ipv6->sixteen[1], ipv6->sixteen[2],
1083                               ipv6->sixteen[3], ipv6->sixteen[4], ipv6->sixteen[5], ipv6->sixteen[6], ipv6->sixteen[7]);
1084 #elif LITTLE_ENDIAN
1085         result = BufferPrintf(buffer, "%x:%x:%x:%x:%x:%x:%x:%x", ipv6->sixteen[7], ipv6->sixteen[6], ipv6->sixteen[5],
1086                               ipv6->sixteen[4], ipv6->sixteen[3], ipv6->sixteen[2], ipv6->sixteen[1], ipv6->sixteen[0]);
1087 #else
1088 #warning "Unrecognized endianness, assuming big endian"
1089         result = BufferPrintf(buffer, "%x:%x:%x:%x:%x:%x:%x:%x", ipv6->sixteen[0], ipv6->sixteen[1], ipv6->sixteen[2],
1090                               ipv6->sixteen[3], ipv6->sixteen[4], ipv6->sixteen[5], ipv6->sixteen[6], ipv6->sixteen[7]);
1091 #endif
1092     }
1093     else
1094     {
1095         buffer = NULL;
1096     }
1097     if (result < 0)
1098     {
1099         BufferDestroy(buffer);
1100         return NULL;
1101     }
1102     return buffer;
1103 }
1104 
IPAddressGetPort(IPAddress * address)1105 int IPAddressGetPort(IPAddress *address)
1106 {
1107     if (!address)
1108     {
1109         return -1;
1110     }
1111     int port = -1;
1112     if (address->type == IP_ADDRESS_TYPE_IPV4)
1113     {
1114         struct IPV4Address *ipv4 = (struct IPV4Address *)address->address;
1115         port = ipv4->port;
1116     }
1117     else if (address->type == IP_ADDRESS_TYPE_IPV6)
1118     {
1119         struct IPV6Address *ipv6 = (struct IPV6Address *)address->address;
1120         port = ipv6->port;
1121     }
1122     else
1123     {
1124         return -1;
1125     }
1126     return port;
1127 }
1128 
1129 /*
1130  * Comparison for IPV4 addresses
1131  */
IPV4Compare(struct IPV4Address * a,struct IPV4Address * b)1132 static int IPV4Compare(struct IPV4Address *a, struct IPV4Address *b)
1133 {
1134     int i = 0;
1135     for (i = 0; i < 4; ++i)
1136     {
1137         if (a->octets[i] != b->octets[i])
1138         {
1139             return 0;
1140         }
1141     }
1142     return 1;
1143 }
1144 
1145 /*
1146  * Comparison for IPV6 addresses
1147  */
IPV6Compare(struct IPV6Address * a,struct IPV6Address * b)1148 static int IPV6Compare(struct IPV6Address *a, struct IPV6Address *b)
1149 {
1150     int i = 0;
1151     for (i = 0; i < 8; ++i)
1152     {
1153         if (a->sixteen[i] != b->sixteen[i])
1154         {
1155             return 0;
1156         }
1157     }
1158     return 1;
1159 }
1160 
IPAddressIsEqual(IPAddress * a,IPAddress * b)1161 int IPAddressIsEqual(IPAddress *a, IPAddress *b)
1162 {
1163     /*
1164      * We do not support IPV4 versus IPV6 comparisons.
1165      * This is trickier than what it seems, since even the IPV6 representation of an IPV6 address is not
1166      * clear yet.
1167      */
1168      if (!a || !b)
1169      {
1170          return -1;
1171      }
1172      if (a->type != b->type)
1173      {
1174          return -1;
1175      }
1176      if (a->type == IP_ADDRESS_TYPE_IPV4)
1177      {
1178          return IPV4Compare((struct IPV4Address *)a->address, (struct IPV4Address *)b->address);
1179      }
1180      else if (a->type == IP_ADDRESS_TYPE_IPV6)
1181      {
1182          return IPV6Compare((struct IPV6Address *)a->address, (struct IPV6Address *)b->address);
1183      }
1184      return -1;
1185 }
1186 
1187 /*
1188  * Sorting comparison for IPV4 addresses
1189  */
IPV4CompareLess(struct IPV4Address * a,struct IPV4Address * b)1190 static bool IPV4CompareLess(struct IPV4Address *a, struct IPV4Address *b)
1191 {
1192     int i = 0;
1193     for (i = 0; i < 4; ++i)
1194     {
1195         if (a->octets[i] > b->octets[i])
1196         {
1197             return false;
1198         }
1199         else if (a->octets[i] < b->octets[i])
1200         {
1201             return true;
1202         }
1203     }
1204 
1205     return false;
1206 }
1207 
1208 /*
1209  * Sorting comparison for IPV6 addresses
1210  */
IPV6CompareLess(struct IPV6Address * a,struct IPV6Address * b)1211 static bool IPV6CompareLess(struct IPV6Address *a, struct IPV6Address *b)
1212 {
1213     int i = 0;
1214     for (i = 0; i < 8; ++i)
1215     {
1216         if (a->sixteen[i] > b->sixteen[i])
1217         {
1218             return false;
1219         }
1220         else if (a->sixteen[i] < b->sixteen[i])
1221         {
1222             return true;
1223         }
1224     }
1225 
1226     return false;
1227 }
1228 
IPAddressCompareLess(IPAddress * a,IPAddress * b)1229 bool IPAddressCompareLess(IPAddress *a, IPAddress *b)
1230 {
1231     /*
1232      * We do not support IPV4 versus IPV6 comparisons.
1233      * This is trickier than what it seems, since even the IPV6 representation of an IPV6 address is not
1234      * clear yet.
1235      */
1236     if (a == NULL || b == NULL)
1237     {
1238         return true;
1239     }
1240 
1241     assert(a->type == IP_ADDRESS_TYPE_IPV4 || a->type == IP_ADDRESS_TYPE_IPV6);
1242     assert(b->type == IP_ADDRESS_TYPE_IPV4 || b->type == IP_ADDRESS_TYPE_IPV6);
1243 
1244     // If not same type - Sort IPv4 BEFORE any other types:
1245     if (a->type != b->type)
1246     {
1247         if (a->type == IP_ADDRESS_TYPE_IPV4)
1248         {
1249             return true;
1250         }
1251         else
1252         {
1253             assert(b->type == IP_ADDRESS_TYPE_IPV4);
1254             return false;
1255         }
1256     }
1257 
1258     assert(a->type == b->type);
1259     IPAddressVersion type = a->type;
1260 
1261     if (type == IP_ADDRESS_TYPE_IPV4)
1262     {
1263         return IPV4CompareLess((struct IPV4Address *)a->address, (struct IPV4Address *)b->address);
1264     }
1265 
1266     assert(type == IP_ADDRESS_TYPE_IPV6);
1267 
1268     return IPV6CompareLess((struct IPV6Address *)a->address, (struct IPV6Address *)b->address);
1269 }
1270 
IPAddressIsIPAddress(Buffer * source,IPAddress ** address)1271 bool IPAddressIsIPAddress(Buffer *source, IPAddress **address)
1272 {
1273     if (!source || !BufferData(source))
1274     {
1275         return false;
1276     }
1277     bool create_object = false;
1278     if (address)
1279     {
1280         create_object = true;
1281     }
1282     const char *pad = BufferData(source);
1283     struct IPV4Address *ipv4 = NULL;
1284     struct IPV6Address *ipv6 = NULL;
1285     ipv4 = (struct IPV4Address *)xmalloc(sizeof(struct IPV4Address));
1286     ipv6 = (struct IPV6Address *)xmalloc(sizeof(struct IPV6Address));
1287     if (IPV4_parser(pad, ipv4) == 0)
1288     {
1289         free (ipv6);
1290         if (create_object)
1291         {
1292             *address = (IPAddress *)xmalloc(sizeof(IPAddress));
1293             (*address)->type = IP_ADDRESS_TYPE_IPV4;
1294             (*address)->address = (void *)ipv4;
1295         }
1296         else
1297         {
1298             /*
1299              * We know it is a valid IPV4 address and we know we don't need the
1300              * IPV4 structure.
1301              */
1302             free (ipv4);
1303         }
1304     }
1305     else if (IPV6_parser(pad, ipv6) == 0)
1306     {
1307         free (ipv4);
1308         if (create_object)
1309         {
1310             *address = (IPAddress *)xmalloc(sizeof(IPAddress));
1311             (*address)->type = IP_ADDRESS_TYPE_IPV6;
1312             (*address)->address = (void *)ipv6;
1313         }
1314         else
1315         {
1316             /*
1317              * We know it is a valid IPV6 address and we know we don't need the
1318              * IPV6 structure.
1319              */
1320             free (ipv6);
1321         }
1322     }
1323     else
1324     {
1325         /*
1326          * It was not a valid IP address.
1327          */
1328         free (ipv4);
1329         free (ipv6);
1330         return false;
1331     }
1332     return true;
1333 }
1334