1 /*
2  *  Copyright (c) 2021, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /**
30  * @file
31  *   This file implements IPv4 address related functionality.
32  */
33 
34 #include "ip4_address.hpp"
35 
36 #include "common/code_utils.hpp"
37 #include "common/numeric_limits.hpp"
38 
39 namespace ot {
40 namespace Ip4 {
41 
FromString(const char * aString)42 Error Address::FromString(const char *aString)
43 {
44     constexpr char kSeperatorChar = '.';
45     constexpr char kNullChar      = '\0';
46 
47     Error error = kErrorParse;
48 
49     for (uint8_t index = 0;; index++)
50     {
51         uint16_t value         = 0;
52         uint8_t  hasFirstDigit = false;
53 
54         for (char digitChar = *aString;; ++aString, digitChar = *aString)
55         {
56             if ((digitChar < '0') || (digitChar > '9'))
57             {
58                 break;
59             }
60 
61             value = static_cast<uint16_t>((value * 10) + static_cast<uint8_t>(digitChar - '0'));
62             VerifyOrExit(value <= NumericLimits<uint8_t>::kMax);
63             hasFirstDigit = true;
64         }
65 
66         VerifyOrExit(hasFirstDigit);
67 
68         mBytes[index] = static_cast<uint8_t>(value);
69 
70         if (index == sizeof(Address) - 1)
71         {
72             break;
73         }
74 
75         VerifyOrExit(*aString == kSeperatorChar);
76         aString++;
77     }
78 
79     VerifyOrExit(*aString == kNullChar);
80     error = kErrorNone;
81 
82 exit:
83     return error;
84 }
85 
ToString(void) const86 Address::InfoString Address::ToString(void) const
87 {
88     InfoString string;
89 
90     string.Append("%d.%d.%d.%d", mBytes[0], mBytes[1], mBytes[2], mBytes[3]);
91 
92     return string;
93 }
94 
95 } // namespace Ip4
96 } // namespace ot
97