]> git.ipfire.org Git - people/amarx/ipfire-3.x.git/blob - network/patches/0001-inetcalc-Allow-build-on-64-bit-architectures.patch
fec5b2c742709ccd417ade63b74ac0a1ee158cf1
[people/amarx/ipfire-3.x.git] / network / patches / 0001-inetcalc-Allow-build-on-64-bit-architectures.patch
1 From cf3fb03ccc299b1233fa1a3cc4ce66520c324e70 Mon Sep 17 00:00:00 2001
2 From: Michael Tremer <michael.tremer@ipfire.org>
3 Date: Wed, 21 Oct 2015 18:42:06 +0200
4 Subject: [PATCH] inetcalc: Allow build on 64 bit architectures
5
6 inetcalc previously used a GCC extension that was only
7 available on 64 bit platforms. This patch changes the
8 code to use struct in6_addr instead of __uint128_t for
9 storing IP addresses.
10
11 Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
12 ---
13 src/inetcalc.c | 47 +++++++++++++++++++++++++++++++++--------------
14 1 file changed, 33 insertions(+), 14 deletions(-)
15
16 diff --git a/src/inetcalc.c b/src/inetcalc.c
17 index f821d6ed41a6..ba692542aba7 100644
18 --- a/src/inetcalc.c
19 +++ b/src/inetcalc.c
20 @@ -30,17 +30,26 @@
21
22 typedef struct ip_address {
23 int family;
24 - __uint128_t addr;
25 + struct in6_addr addr;
26 int prefix;
27 } ip_address_t;
28
29 -static __uint128_t prefix_to_bitmask(int prefix) {
30 - __uint128_t bitmask = ~0;
31 +static struct in6_addr prefix_to_bitmask(int prefix) {
32 + assert(prefix <= 128);
33
34 - for (int i = 0; i < 128 - prefix; i++)
35 - bitmask >>= 1;
36 + struct in6_addr bitmask;
37
38 - return bitmask;
39 + for (int i = 0; i < 16; i++)
40 + bitmask.s6_addr[i] = 0;
41 +
42 + for (int i = prefix, j = 0; i > 0; i -= 8, j++) {
43 + if (i >= 8)
44 + bitmask.s6_addr[j] = 0xff;
45 + else
46 + bitmask.s6_addr[j] = 0xff << (8 - i);
47 + }
48 +
49 + return bitmask;
50 }
51
52 static int bitmask_to_prefix(uint32_t bits) {
53 @@ -171,7 +180,7 @@ static int ip_address_eq(const ip_address_t* a1, const ip_address_t* a2) {
54 if (a1->family != a2->family)
55 return 1;
56
57 - if (a1->addr != a2->addr)
58 + if (a1->addr.s6_addr != a2->addr.s6_addr)
59 return 1;
60
61 if (a1->prefix != a2->prefix)
62 @@ -184,7 +193,7 @@ static int ip_address_gt(const ip_address_t* a1, const ip_address_t* a2) {
63 if (a1->family != a2->family || a1->prefix != a2->prefix)
64 return -1;
65
66 - if (a1->addr > a2->addr)
67 + if (a1->addr.s6_addr > a2->addr.s6_addr)
68 return 0;
69
70 return 1;
71 @@ -193,7 +202,7 @@ static int ip_address_gt(const ip_address_t* a1, const ip_address_t* a2) {
72 static int ip_address_format_string(char* buffer, size_t size, const ip_address_t* ip) {
73 assert(ip->family == AF_INET || ip->family == AF_INET6);
74
75 - const char* p = inet_ntop(ip->family, &ip->addr, buffer, size);
76 + const char* p = inet_ntop(ip->family, &ip->addr.s6_addr, buffer, size);
77 if (!p)
78 return errno;
79
80 @@ -218,21 +227,25 @@ static void ip_address_print(const ip_address_t* ip) {
81 static void ip_address_make_network(ip_address_t* net, const ip_address_t* ip) {
82 assert(ip->prefix >= 0);
83
84 - __uint128_t mask = prefix_to_bitmask(ip->prefix);
85 + struct in6_addr mask = prefix_to_bitmask(ip->prefix);
86
87 net->family = ip->family;
88 net->prefix = ip->prefix;
89 - net->addr = ip->addr & mask;
90 +
91 + for (int i = 0; i < 16; i++)
92 + net->addr.s6_addr[i] = ip->addr.s6_addr[i] & mask.s6_addr[i];
93 }
94
95 static void ip_address_make_broadcast(ip_address_t* broadcast, const ip_address_t* ip) {
96 assert(ip->family == AF_INET && ip->prefix >= 0);
97
98 - __uint128_t mask = prefix_to_bitmask(ip->prefix);
99 + struct in6_addr mask = prefix_to_bitmask(ip->prefix);
100
101 broadcast->family = ip->family;
102 broadcast->prefix = ip->prefix;
103 - broadcast->addr = ip->addr | ~mask;
104 +
105 + for (int i = 0; i < 16; i++)
106 + broadcast->addr.s6_addr[i] = ip->addr.s6_addr[i] | ~mask.s6_addr[i];
107 }
108
109 static int action_check(const int family, const char* address) {
110 @@ -342,7 +355,13 @@ static int action_prefix(const int family, const char* addr1, const char* addr2)
111 if (r)
112 return r;
113
114 - uint32_t mask = ntohl(network.addr ^ broadcast.addr);
115 + struct in6_addr netmask;
116 + for (int i = 0; i < 16; i++)
117 + netmask.s6_addr[i] = network.addr.s6_addr[i] ^ broadcast.addr.s6_addr[i];
118 +
119 + uint32_t mask = netmask.s6_addr[0] << 24 | netmask.s6_addr[1] << 16 |
120 + netmask.s6_addr[2] << 8 | netmask.s6_addr[3];
121 +
122 int prefix = bitmask_to_prefix(~mask);
123 if (prefix < 0)
124 return 1;
125 --
126 2.4.3
127