chiark / gitweb /
c4cb3337ae7efe852cee9da1a304e74ed85bdc39
[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 <net/if.h>
24
25 #include "net-util.h"
26 #include "log.h"
27 #include "utf8.h"
28 #include "util.h"
29 #include "conf-parser.h"
30
31 bool net_match_config(const struct ether_addr *match_mac,
32                       const char *match_path,
33                       const char *match_driver,
34                       const char *match_type,
35                       const char *match_name,
36                       struct udev_device *device) {
37         const char *property;
38
39         assert(device);
40
41         if (match_mac) {
42                 property = udev_device_get_sysattr_value(device, "address");
43                 if (!property || memcmp(match_mac, ether_aton(property), ETH_ALEN)) {
44                         log_debug("Interface MAC address (%s) did not match MACAddress=%s",
45                                   property, ether_ntoa(match_mac));
46                         return 0;
47                 }
48         }
49
50         if (match_path) {
51                 property = udev_device_get_property_value(device, "ID_PATH");
52                 if (!streq_ptr(match_path, property)) {
53                         log_debug("Interface persistent path (%s) did not match Path=%s",
54                                   property, match_path);
55                         return 0;
56                 }
57         }
58
59         if (match_driver) {
60                 property = udev_device_get_driver(device);
61                 if (!streq_ptr(match_driver, property)) {
62                         log_debug("Interface device driver (%s) did not match Driver=%s",
63                                   property, match_driver);
64                         return 0;
65                 }
66         }
67
68         if (match_type) {
69                 property = udev_device_get_devtype(device);
70                 if (!streq_ptr(match_type, property)) {
71                         log_debug("Interface type (%s) did not match Type=%s",
72                                   property, match_type);
73                         return 0;
74                 }
75         }
76
77         if (match_name) {
78                 property = udev_device_get_sysname(device);
79                 if (!streq_ptr(match_name, property)) {
80                         log_debug("Interface name (%s) did not match Name=%s",
81                                   property, match_name);
82                         return 0;
83                 }
84         }
85
86         return 1;
87 }
88
89 int config_parse_ifname(const char *unit,
90                         const char *filename,
91                         unsigned line,
92                         const char *section,
93                         const char *lvalue,
94                         int ltype,
95                         const char *rvalue,
96                         void *data,
97                         void *userdata) {
98
99         char **s = data;
100         char *n;
101
102         assert(filename);
103         assert(lvalue);
104         assert(rvalue);
105         assert(data);
106
107         n = strdup(rvalue);
108         if (!n)
109                 return log_oom();
110
111         if (!ascii_is_valid(n) || strlen(n) >= IFNAMSIZ) {
112                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
113                            "Interface name is not ASCII clean or is too long, ignoring assignment: %s", rvalue);
114                 free(n);
115                 return 0;
116         }
117
118         free(*s);
119         if (*n)
120                 *s = n;
121         else {
122                 free(n);
123                 *s = NULL;
124         }
125
126         return 0;
127 }
128
129 int config_parse_hwaddr(const char *unit,
130                         const char *filename,
131                         unsigned line,
132                         const char *section,
133                         const char *lvalue,
134                         int ltype,
135                         const char *rvalue,
136                         void *data,
137                         void *userdata) {
138         struct ether_addr **hwaddr = data;
139         struct ether_addr *n;
140         int r;
141
142         assert(filename);
143         assert(lvalue);
144         assert(rvalue);
145         assert(data);
146
147         n = new0(struct ether_addr, 1);
148         if (!n)
149                 return log_oom();
150
151         r = sscanf(rvalue, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
152                    &n->ether_addr_octet[0],
153                    &n->ether_addr_octet[1],
154                    &n->ether_addr_octet[2],
155                    &n->ether_addr_octet[3],
156                    &n->ether_addr_octet[4],
157                    &n->ether_addr_octet[5]);
158         if (r != 6) {
159                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
160                            "Not a valid MAC address, ignoring assignment: %s", rvalue);
161                 free(n);
162                 return 0;
163         }
164
165         free(*hwaddr);
166         *hwaddr = n;
167
168         return 0;
169 }