]> git.ipfire.org Git - people/ms/network.git/blob - src/networkd/address.h
Makefile: Fix typo in localstatedir
[people/ms/network.git] / src / networkd / address.h
1 /*#############################################################################
2 # #
3 # IPFire.org - A linux based firewall #
4 # Copyright (C) 2023 IPFire Network Development Team #
5 # #
6 # This program is free software: you can redistribute it and/or modify #
7 # it under the terms of the GNU General Public License as published by #
8 # the Free Software Foundation, either version 3 of the License, or #
9 # (at your option) any later version. #
10 # #
11 # This program 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 #
14 # GNU General Public License for more details. #
15 # #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
18 # #
19 #############################################################################*/
20
21 #ifndef NETWORKD_ADDRESS_H
22 #define NETWORKD_ADDRESS_H
23
24 #include <errno.h>
25 #include <netinet/ether.h>
26 #include <string.h>
27 #include <sys/random.h>
28
29 #include "logging.h"
30
31 typedef struct ether_addr nw_address_t;
32
33 enum {
34 NW_ADDRESS_MULTICAST = (1 << 0),
35 NW_ADDRESS_SOFTWAREASSIGNED = (1 << 1),
36 };
37
38 static inline int nw_address_from_string(nw_address_t* addr, const char* s) {
39 if (!s)
40 return -EINVAL;
41
42 struct ether_addr* p = ether_aton_r(s, addr);
43 if (!p)
44 return -errno;
45
46 return 0;
47 }
48
49 static inline char* nw_address_to_string(const nw_address_t* addr) {
50 char buffer[20];
51
52 char* p = ether_ntoa_r(addr, buffer);
53 if (!p)
54 return NULL;
55
56 return strdup(buffer);
57 }
58
59 static inline int nw_address_generate(nw_address_t* addr) {
60 ssize_t bytes = getrandom(addr, sizeof(*addr), 0);
61 if (bytes < 0) {
62 ERROR("getrandom() failed: %m\n");
63 return 1;
64 }
65
66 // Check if we filled the entire buffer
67 if (bytes < (ssize_t)sizeof(*addr)) {
68 ERROR("Could not gather enough randomness\n");
69 return 1;
70 }
71
72 // Clear the multicast bit
73 addr->ether_addr_octet[0] &= ~NW_ADDRESS_MULTICAST;
74
75 // Set the software-generated bit
76 addr->ether_addr_octet[0] |= NW_ADDRESS_SOFTWAREASSIGNED;
77
78 return 0;
79 }
80
81 static inline int nw_address_is_multicast(const nw_address_t* addr) {
82 return (addr->ether_addr_octet[0] & NW_ADDRESS_MULTICAST);
83 }
84
85 #endif /* NETWORKD_ADDRESS_H */