chiark / gitweb /
udev: net_setup_link - don't use Description as Alias
[elogind.git] / src / shared / net-util.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4  This file is part of systemd.
5
6  Copyright (C) 2013 Tom Gundersen <teg@jklm.no>
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <netinet/ether.h>
23 #include <linux/if.h>
24 #include <arpa/inet.h>
25
26 #include "net-util.h"
27 #include "log.h"
28 #include "utf8.h"
29 #include "util.h"
30 #include "conf-parser.h"
31
32 bool net_match_config(const struct ether_addr *match_mac,
33                       const char *match_path,
34                       const char *match_driver,
35                       const char *match_type,
36                       const char *match_name,
37                       const char *dev_mac,
38                       const char *dev_path,
39                       const char *dev_driver,
40                       const char *dev_type,
41                       const char *dev_name) {
42
43         if (match_mac) {
44                 if (!dev_mac || memcmp(match_mac, ether_aton(dev_mac), ETH_ALEN)) {
45                         log_debug("Interface MAC address (%s) did not match MACAddress=%s",
46                                   dev_mac, ether_ntoa(match_mac));
47                         return 0;
48                 }
49         }
50
51         if (match_path) {
52                 if (!streq_ptr(match_path, dev_path)) {
53                         log_debug("Interface persistent path (%s) did not match Path=%s",
54                                   dev_path, match_path);
55                         return 0;
56                 }
57         }
58
59         if (match_driver) {
60                 if (!streq_ptr(match_driver, dev_driver)) {
61                         log_debug("Interface device driver (%s) did not match Driver=%s",
62                                   dev_driver, match_driver);
63                         return 0;
64                 }
65         }
66
67         if (match_type) {
68                 if (!streq_ptr(match_type, dev_type)) {
69                         log_debug("Interface type (%s) did not match Type=%s",
70                                   dev_type, match_type);
71                         return 0;
72                 }
73         }
74
75         if (match_name) {
76                 if (!streq_ptr(match_name, dev_name)) {
77                         log_debug("Interface name (%s) did not match Name=%s",
78                                   dev_name, match_name);
79                         return 0;
80                 }
81         }
82
83         return 1;
84 }
85
86 int config_parse_ifname(const char *unit,
87                         const char *filename,
88                         unsigned line,
89                         const char *section,
90                         const char *lvalue,
91                         int ltype,
92                         const char *rvalue,
93                         void *data,
94                         void *userdata) {
95
96         char **s = data;
97         char *n;
98
99         assert(filename);
100         assert(lvalue);
101         assert(rvalue);
102         assert(data);
103
104         n = strdup(rvalue);
105         if (!n)
106                 return log_oom();
107
108         if (!ascii_is_valid(n) || strlen(n) >= IFNAMSIZ) {
109                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
110                            "Interface name is not ASCII clean or is too long, ignoring assignment: %s", rvalue);
111                 free(n);
112                 return 0;
113         }
114
115         free(*s);
116         if (*n)
117                 *s = n;
118         else {
119                 free(n);
120                 *s = NULL;
121         }
122
123         return 0;
124 }
125
126 int config_parse_ifalias(const char *unit,
127                          const char *filename,
128                          unsigned line,
129                          const char *section,
130                          const char *lvalue,
131                          int ltype,
132                          const char *rvalue,
133                          void *data,
134                          void *userdata) {
135
136         char **s = data;
137         char *n;
138
139         assert(filename);
140         assert(lvalue);
141         assert(rvalue);
142         assert(data);
143
144         n = strdup(rvalue);
145         if (!n)
146                 return log_oom();
147
148         if (!ascii_is_valid(n) || strlen(n) >= IFALIASZ) {
149                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
150                            "Interface alias is not ASCII clean or is too long, ignoring assignment: %s", rvalue);
151                 free(n);
152                 return 0;
153         }
154
155         free(*s);
156         if (*n)
157                 *s = n;
158         else {
159                 free(n);
160                 *s = NULL;
161         }
162
163         return 0;
164 }
165
166 int config_parse_hwaddr(const char *unit,
167                         const char *filename,
168                         unsigned line,
169                         const char *section,
170                         const char *lvalue,
171                         int ltype,
172                         const char *rvalue,
173                         void *data,
174                         void *userdata) {
175         struct ether_addr **hwaddr = data;
176         struct ether_addr *n;
177         int r;
178
179         assert(filename);
180         assert(lvalue);
181         assert(rvalue);
182         assert(data);
183
184         n = new0(struct ether_addr, 1);
185         if (!n)
186                 return log_oom();
187
188         r = sscanf(rvalue, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
189                    &n->ether_addr_octet[0],
190                    &n->ether_addr_octet[1],
191                    &n->ether_addr_octet[2],
192                    &n->ether_addr_octet[3],
193                    &n->ether_addr_octet[4],
194                    &n->ether_addr_octet[5]);
195         if (r != 6) {
196                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
197                            "Not a valid MAC address, ignoring assignment: %s", rvalue);
198                 free(n);
199                 return 0;
200         }
201
202         free(*hwaddr);
203         *hwaddr = n;
204
205         return 0;
206 }
207
208 int net_parse_inaddr(const char *address, unsigned char *family, void *dst) {
209         int r;
210
211         assert(address);
212         assert(family);
213         assert(dst);
214
215         /* IPv4 */
216         r = inet_pton(AF_INET, address, dst);
217         if (r > 0)
218                 *family = AF_INET; /* successfully parsed IPv4 address */
219         else  if (r < 0)
220                 return -errno;
221         else {
222                 /* not an IPv4 address, so let's try IPv6 */
223                 r = inet_pton(AF_INET6, address, dst);
224                 if (r > 0)
225                         *family = AF_INET6; /* successfully parsed IPv6 address */
226                 else if (r < 0)
227                         return -errno;
228                 else
229                         return -EINVAL;
230         }
231
232         return 0;
233 }