9cd514c7643ed9a69c312ce5a02fe1f9bef4f305
[libvscmgmt.git] / utils / ipv4.c
1 /*
2  * ipv4.c: Utilities for Virtualized Super Computer Management
3  *
4  * Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
19  */
20
21 #include "utils.h"
22
23 /*
24  * IPv4
25  */
26
27 /**
28  * Appends a duplicate of the given IPv4 to the list.
29  *
30  * Always returns a pointer to the first IPv4 item in the list, so that this
31  * function can be used for initialization and for appending.
32  */
33 struct VscMgmtIpv4 * /* ipv4_list */
34 vsc_mgmt_ipv4_list_append (struct VscMgmtError *error,
35                            struct VscMgmtIpv4 *ipv4_list,
36                            const struct VscMgmtIpv4 *ipv4)
37 {
38         struct VscMgmtIpv4 *ipv4_duplicate = NULL;
39
40         VSC_MGMT__ASSERT (error != NULL);
41         VSC_MGMT__ASSERT (! error->occured);
42
43         ipv4_duplicate = vsc_mgmt_memdup (error, ipv4, sizeof (struct VscMgmtIpv4));
44
45         if (error->occured) {
46                 VSC_MGMT__APPEND_ERROR0 (error, VSC_MGMT__CODE__TRACE);
47                 return NULL;
48         }
49
50         ipv4_duplicate->next = NULL;
51
52         return (struct VscMgmtIpv4 *) vsc_mgmt_list_append ((struct VscMgmtList *) ipv4_list,
53                                                             (struct VscMgmtList *) ipv4_duplicate);
54 }
55
56 /**
57  * Recursively frees the given IPv4 list.
58  */
59 void
60 vsc_mgmt_ipv4_list_free (struct VscMgmtIpv4 *ipv4_list)
61 {
62         vsc_mgmt_list_free ((struct VscMgmtList *) ipv4_list);
63 }
64
65 /**
66  * Parses an IPv4 from its string representation.
67  */
68 void
69 vsc_mgmt_ipv4_parse (struct VscMgmtError *error, const char *ipv4_string,
70                      struct VscMgmtIpv4 *ipv4)
71 {
72         int i;
73         char *tail = (char *) ipv4_string;
74         int number = 0;
75
76         VSC_MGMT__ASSERT (error != NULL);
77         VSC_MGMT__ASSERT (! error->occured);
78
79         for (i = 0; i < 4; i++) {
80                 number = vsc_mgmt_strtoi (error, tail, &tail, 10);
81
82                 if (error->occured) {
83                         VSC_MGMT__APPEND_ERROR2 (error, VSC_MGMT__CODE__INVALID_IPV4_STRING,
84                                                  "'%s'", ipv4_string);
85                         return;
86                 }
87
88                 if (i < 3) {
89                         if (tail == NULL || *tail != '.') {
90                                 VSC_MGMT__ERROR2 (error, VSC_MGMT__CODE__INVALID_IPV4_STRING,
91                                                   "'%s' must consist of 4 elements separated "
92                                                   "by '.'", ipv4_string);
93                                 return;
94                         }
95
96                         ++tail;
97                 } else {
98                         if (*tail != '\0') {
99                                 VSC_MGMT__ERROR2 (error, VSC_MGMT__CODE__INVALID_IPV4_STRING,
100                                                   "'%s' has invalid suffix '%s'", ipv4_string,
101                                                   tail);
102                                 return;
103                         }
104                 }
105
106                 if (number < 0 || number > 255) {
107                         VSC_MGMT__ERROR2 (error, VSC_MGMT__CODE__INVALID_IPV4_STRING,
108                                           "Elements of '%s' must be in [0..255] reange",
109                                           ipv4_string);
110                         return;
111                 }
112
113                 ipv4->bytes[i] = number;
114         }
115 }
116
117 /**
118  * Formats an IPv4 to its string representation.
119  */
120 void
121 vsc_mgmt_ipv4_format (const struct VscMgmtIpv4 *ipv4, char *ipv4_string)
122 {
123         snprintf (ipv4_string, VSC_MGMT__IPV4__STRING_SIZE, "%u.%u.%u.%u",
124                   ipv4->bytes[0], ipv4->bytes[1], ipv4->bytes[2], ipv4->bytes[3]);
125 }