summaryrefslogtreecommitdiff
path: root/net-dns/dnsmasq/files/dnsmasq-2.90-gcc15.patch
blob: a0efca3ab687fa981d42c32692da5cd71e85913a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
https://bugs.gentoo.org/943671

From da2cc84854a01dd08a8bb4161428be20b83a5ec7 Mon Sep 17 00:00:00 2001
From: gen2dev <gen2dev@qsr.us>
Date: Sun, 1 Dec 2024 22:53:16 +0000
Subject: [PATCH] Fix GCC-15, C23 compatibility and
 -Wincompatible-pointer-types errors

A bug in gentoo linux https://bugs.gentoo.org/945183 reported that dnsmasq 2.90 fails to compile with GCC 15.

The issue is that while previous versions of GCC defaulted to the C17 standard and C23 could be selected with
"-std=c23" or "-std=gnu23", GCC 15 defaults to C23. In C23 incompatible pointer types are an error instead of
a warning, so the "int (*callback)()" incomplete prototypes cause errors.

For example, compiling dnsmasq 2.90 with gcc 14.2.1 and "-std=gnu23" fails with errors such as:
    lease.c: In function `lease_find_interfaces':
    lease.c:467:34: warning: passing argument 3 of `iface_enumerate' from incompatible pointer type [-Wincompatible-pointer-types[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wincompatible-pointer-types]]
      467 |   iface_enumerate(AF_INET, &now, find_interface_v4);
          |                                  ^~~~~~~~~~~~~~~~~
          |                                  |
          |                                  int (*)(struct in_addr,  int,  char *, struct in_addr,  struct in_addr,  void *)
    In file included from lease.c:17:
    dnsmasq.h:1662:50: note: expected `int (*)(void)' but argument is of type `int (*)(struct in_addr,  int,  char *, struct in_addr,  struct in_addr,  void *)'
     1662 | int iface_enumerate(int family, void *parm, int (callback)());
          |                                             ~~~~~^~~~~~~~~~~

This patch uses a typedef'ed union of pointer types to get type checking of the pointers. If that's too complicated,
another way might be to use (void *) casts to disable type checking.

Also, some of the IPv6 callbacks had "int preferred, int valid" and some had
"unsigned int preferred, unsigned int valid". This patch changes them all to "unsigned int"
so they're the same and to avoid casting "u32" to "int", eg:
    u32 preferred = 0xffffffff;
    callback(..., (int)preferred, ...)
Even if those cast values aren't used in the callback, casting u32 to "int" feels bad, especially if "int" is 32 bits.
---
 src/arp.c     |  2 +-
 src/bpf.c     | 14 +++++++-------
 src/dhcp.c    |  4 ++--
 src/dhcp6.c   |  8 ++++----
 src/dnsmasq.h |  8 +++++++-
 src/lease.c   |  6 +++---
 src/netlink.c | 12 ++++++------
 src/network.c |  6 +++---
 src/radv.c    | 14 +++++++-------
 9 files changed, 40 insertions(+), 34 deletions(-)

diff --git a/src/arp.c b/src/arp.c
index 0a5a9bf..6ff1f01 100644
--- a/src/arp.c
+++ b/src/arp.c
@@ -152,7 +152,7 @@ int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now)
 	 if (arp->status != ARP_EMPTY)
 	   arp->status = ARP_MARK;
        
-       iface_enumerate(AF_UNSPEC, NULL, filter_mac);
+       iface_enumerate(AF_UNSPEC, NULL, (callback_t){.af_unspec=filter_mac});
        
        /* Remove all unconfirmed entries to old list. */
        for (arp = arps, up = &arps; arp; arp = tmp)
diff --git a/src/bpf.c b/src/bpf.c
index 62b589c..82d0125 100644
--- a/src/bpf.c
+++ b/src/bpf.c
@@ -47,7 +47,7 @@ static union all_addr del_addr;
 
 #if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
 
-int arp_enumerate(void *parm, int (*callback)())
+int arp_enumerate(void *parm, callback_t callback)
 {
   int mib[6];
   size_t needed;
@@ -91,7 +91,7 @@ int arp_enumerate(void *parm, int (*callback)())
       rtm = (struct rt_msghdr *)next;
       sin2 = (struct sockaddr_inarp *)(rtm + 1);
       sdl = (struct sockaddr_dl *)((char *)sin2 + SA_SIZE(sin2));
-      if (!(*callback)(AF_INET, &sin2->sin_addr, LLADDR(sdl), sdl->sdl_alen, parm))
+      if (!callback.af_unspec(AF_INET, &sin2->sin_addr, LLADDR(sdl), sdl->sdl_alen, parm))
 	return 0;
     }
 
@@ -107,7 +107,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
 
   if (family == AF_UNSPEC)
 #if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
-    return  arp_enumerate(parm, callback);
+    return  arp_enumerate(parm, callback.af_unspec);
 #else
   return 0; /* need code for Solaris and MacOS*/
 #endif
@@ -147,7 +147,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
 		broadcast = ((struct sockaddr_in *) addrs->ifa_broadaddr)->sin_addr; 
 	      else 
 		broadcast.s_addr = 0;	      
-	      if (!((*callback)(addr, iface_index, NULL, netmask, broadcast, parm)))
+	      if (!callback.af_inet(addr, iface_index, NULL, netmask, broadcast, parm))
 		goto err;
 	    }
 	  else if (family == AF_INET6)
@@ -212,8 +212,8 @@ int iface_enumerate(int family, void *parm, int (*callback)())
 		  addr->s6_addr[3] = 0;
 		} 
 	     
-	      if (!((*callback)(addr, prefix, scope_id, iface_index, flags,
-				(int) preferred, (int)valid, parm)))
+	      if (!callback.af_inet6(addr, prefix, scope_id, iface_index, flags,
+				(unsigned int) preferred, (unsigned int)valid, parm))
 		goto err;	      
 	    }
 
@@ -223,7 +223,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
 	      /* Assume ethernet again here */
 	      struct sockaddr_dl *sdl = (struct sockaddr_dl *) addrs->ifa_addr;
 	      if (sdl->sdl_alen != 0 && 
-		  !((*callback)(iface_index, ARPHRD_ETHER, LLADDR(sdl), sdl->sdl_alen, parm)))
+		  !callback.af_local(iface_index, ARPHRD_ETHER, LLADDR(sdl), sdl->sdl_alen, parm))
 		goto err;
 	    }
 #endif 
diff --git a/src/dhcp.c b/src/dhcp.c
index 2603c76..009c2a0 100644
--- a/src/dhcp.c
+++ b/src/dhcp.c
@@ -317,7 +317,7 @@ void dhcp_packet(time_t now, int pxe_fd)
 	  match.ind = iface_index;
 	  
 	  if (!daemon->if_addrs ||
-	      !iface_enumerate(AF_INET, &match, check_listen_addrs) ||
+	      !iface_enumerate(AF_INET, &match, (callback_t){.af_inet=check_listen_addrs}) ||
 	      !match.matched)
 	    return;
 	  
@@ -330,7 +330,7 @@ void dhcp_packet(time_t now, int pxe_fd)
       if (relay_upstream4(iface_index, mess, (size_t)sz))
 	return;
       
-      if (!iface_enumerate(AF_INET, &parm, complete_context))
+      if (!iface_enumerate(AF_INET, &parm, (callback_t){.af_inet=complete_context}))
 	return;
 
       /* Check for a relay again after iface_enumerate/complete_context has had
diff --git a/src/dhcp6.c b/src/dhcp6.c
index c9d54dc..303d33c 100644
--- a/src/dhcp6.c
+++ b/src/dhcp6.c
@@ -239,7 +239,7 @@ void dhcp6_packet(time_t now)
 	  relay_upstream6(if_index, (size_t)sz, &from.sin6_addr, from.sin6_scope_id, now))
 	return;
       
-      if (!iface_enumerate(AF_INET6, &parm, complete_context6))
+      if (!iface_enumerate(AF_INET6, &parm, (callback_t){.af_inet6=complete_context6}))
 	return;
       
       /* Check for a relay again after iface_enumerate/complete_context has had
@@ -617,7 +617,7 @@ void make_duid(time_t now)
 	newnow = now - 946684800;
 #endif      
       
-      iface_enumerate(AF_LOCAL, &newnow, make_duid1);
+      iface_enumerate(AF_LOCAL, &newnow, (callback_t){.af_local=make_duid1});
       
       if(!daemon->duid)
 	die("Cannot create DHCPv6 server DUID: %s", NULL, EC_MISC);
@@ -667,7 +667,7 @@ struct cparam {
 
 static int construct_worker(struct in6_addr *local, int prefix, 
 			    int scope, int if_index, int flags, 
-			    int preferred, int valid, void *vparam)
+			    unsigned int preferred, unsigned int valid, void *vparam)
 {
   char ifrn_name[IFNAMSIZ];
   struct in6_addr start6, end6;
@@ -801,7 +801,7 @@ void dhcp_construct_contexts(time_t now)
     if (context->flags & CONTEXT_CONSTRUCTED)
       context->flags |= CONTEXT_GC;
    
-  iface_enumerate(AF_INET6, &param, construct_worker);
+  iface_enumerate(AF_INET6, &param, (callback_t){.af_inet6=construct_worker});
 
   for (up = &daemon->dhcp6, context = daemon->dhcp6; context; context = tmp)
     {
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index a9019ee..abb06c8 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -1662,7 +1662,13 @@ void route_sock(void);
 #endif
 
 /* bpf.c or netlink.c */
-int iface_enumerate(int family, void *parm, int (callback)());
+typedef union {
+	int (*af_unspec)(int family, char *addrp, char *mac, size_t maclen, void *parmv);
+	int (*af_inet)(struct in_addr local, int if_index, char *label, struct in_addr netmask, struct in_addr broadcast, void *vparam);
+	int (*af_inet6)(struct in6_addr *local, int prefix, int scope, int if_index, int flags, unsigned int preferred, unsigned int valid, void *vparam);
+	int (*af_local)(int index, unsigned int type, char *mac, size_t maclen, void *parm);
+} callback_t;
+int iface_enumerate(int family, void *parm, callback_t callback);
 
 /* dbus.c */
 #ifdef HAVE_DBUS
diff --git a/src/lease.c b/src/lease.c
index a133021..06a6ae4 100644
--- a/src/lease.c
+++ b/src/lease.c
@@ -411,7 +411,7 @@ static int find_interface_v4(struct in_addr local, int if_index, char *label,
 #ifdef HAVE_DHCP6
 static int find_interface_v6(struct in6_addr *local,  int prefix,
 			     int scope, int if_index, int flags, 
-			     int preferred, int valid, void *vparam)
+			     unsigned int preferred, unsigned int valid, void *vparam)
 {
   struct dhcp_lease *lease;
 
@@ -468,9 +468,9 @@ void lease_find_interfaces(time_t now)
   for (lease = leases; lease; lease = lease->next)
     lease->new_prefixlen = lease->new_interface = 0;
 
-  iface_enumerate(AF_INET, &now, find_interface_v4);
+  iface_enumerate(AF_INET, &now, (callback_t){.af_inet=find_interface_v4});
 #ifdef HAVE_DHCP6
-  iface_enumerate(AF_INET6, &now, find_interface_v6);
+  iface_enumerate(AF_INET6, &now, (callback_t){.af_inet6=find_interface_v6});
 #endif
 
   for (lease = leases; lease; lease = lease->next)
diff --git a/src/netlink.c b/src/netlink.c
index ef4b5fe..c706339 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -151,7 +151,7 @@ static ssize_t netlink_recv(int flags)
    family = AF_LOCAL finds MAC addresses.
    returns 0 on failure, 1 on success, -1 when restart is required
 */
-int iface_enumerate(int family, void *parm, int (*callback)())
+int iface_enumerate(int family, void *parm, callback_t callback)
 {
   struct sockaddr_nl addr;
   struct nlmsghdr *h;
@@ -247,7 +247,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
 		      }
 		    
 		    if (addr.s_addr && callback_ok)
-		      if (!((*callback)(addr, ifa->ifa_index, label,  netmask, broadcast, parm)))
+		      if (!callback.af_inet(addr, ifa->ifa_index, label,  netmask, broadcast, parm))
 			callback_ok = 0;
 		  }
 		else if (ifa->ifa_family == AF_INET6)
@@ -288,9 +288,9 @@ int iface_enumerate(int family, void *parm, int (*callback)())
 		      flags |= IFACE_PERMANENT;
     		    
 		    if (addrp && callback_ok)
-		      if (!((*callback)(addrp, (int)(ifa->ifa_prefixlen), (int)(ifa->ifa_scope), 
+		      if (!callback.af_inet6(addrp, (int)(ifa->ifa_prefixlen), (int)(ifa->ifa_scope), 
 					(int)(ifa->ifa_index), flags, 
-					(int) preferred, (int)valid, parm)))
+					(unsigned int)preferred, (unsigned int)valid, parm))
 			callback_ok = 0;
 		  }
 	      }
@@ -318,7 +318,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
 
 	    if (!(neigh->ndm_state & (NUD_NOARP | NUD_INCOMPLETE | NUD_FAILED)) &&
 		inaddr && mac && callback_ok)
-	      if (!((*callback)(neigh->ndm_family, inaddr, mac, maclen, parm)))
+	      if (!callback.af_unspec(neigh->ndm_family, inaddr, mac, maclen, parm))
 		callback_ok = 0;
 	  }
 #ifdef HAVE_DHCP6
@@ -342,7 +342,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
 	      }
 
 	    if (mac && callback_ok && !((link->ifi_flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) && 
-		!((*callback)((int)link->ifi_index, (unsigned int)link->ifi_type, mac, maclen, parm)))
+		!callback.af_local((int)link->ifi_index, (unsigned int)link->ifi_type, mac, maclen, parm))
 	      callback_ok = 0;
 	  }
 #endif
diff --git a/src/network.c b/src/network.c
index 0e93c4d..36d9262 100644
--- a/src/network.c
+++ b/src/network.c
@@ -596,7 +596,7 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
 
 static int iface_allowed_v6(struct in6_addr *local, int prefix, 
 			    int scope, int if_index, int flags, 
-			    int preferred, int valid, void *vparam)
+			    unsigned int preferred, unsigned int valid, void *vparam)
 {
   union mysockaddr addr;
   struct in_addr netmask; /* dummy */
@@ -833,12 +833,12 @@ again:
 
   param.spare = spare;
   
-  ret = iface_enumerate(AF_INET6, &param, iface_allowed_v6);
+  ret = iface_enumerate(AF_INET6, &param, (callback_t){.af_inet6=iface_allowed_v6});
   if (ret < 0)
     goto again;
   else if (ret)
     {
-      ret = iface_enumerate(AF_INET, &param, iface_allowed_v4);
+      ret = iface_enumerate(AF_INET, &param, (callback_t){.af_inet=iface_allowed_v4});
       if (ret < 0)
 	goto again;
     }
diff --git a/src/radv.c b/src/radv.c
index d2d3390..f39716c 100644
--- a/src/radv.c
+++ b/src/radv.c
@@ -58,7 +58,7 @@ static int add_prefixes(struct in6_addr *local,  int prefix,
 			unsigned int preferred, unsigned int valid, void *vparam);
 static int iface_search(struct in6_addr *local,  int prefix,
 			int scope, int if_index, int flags, 
-			int prefered, int valid, void *vparam);
+			unsigned int prefered, unsigned int valid, void *vparam);
 static int add_lla(int index, unsigned int type, char *mac, size_t maclen, void *parm);
 static void new_timeout(struct dhcp_context *context, char *iface_name, time_t now);
 static unsigned int calc_lifetime(struct ra_interface *ra);
@@ -307,7 +307,7 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad
 
   /* If no link-local address then we can't advertise since source address of
      advertisement must be link local address: RFC 4861 para 6.1.2. */
-  if (!iface_enumerate(AF_INET6, &parm, add_prefixes) ||
+  if (!iface_enumerate(AF_INET6, &parm, (callback_t){.af_inet6=add_prefixes}) ||
       parm.link_pref_time == 0)
     return;
 
@@ -449,7 +449,7 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad
       put_opt6_long(mtu);
     }
      
-  iface_enumerate(AF_LOCAL, &send_iface, add_lla);
+  iface_enumerate(AF_LOCAL, &send_iface, (callback_t){.af_local=add_lla});
  
   /* RDNSS, RFC 6106, use relevant DHCP6 options */
   (void)option_filter(parm.tags, NULL, daemon->dhcp_opts6);
@@ -823,7 +823,7 @@ time_t periodic_ra(time_t now)
 	  param.iface = context->if_index;
 	  new_timeout(context, param.name, now);
 	}
-      else if (iface_enumerate(AF_INET6, &param, iface_search))
+      else if (iface_enumerate(AF_INET6, &param, (callback_t){.af_inet6=iface_search}))
 	/* There's a context overdue, but we can't find an interface
 	   associated with it, because it's for a subnet we dont 
 	   have an interface on. Probably we're doing DHCP on
@@ -856,7 +856,7 @@ time_t periodic_ra(time_t now)
                     aparam.iface = param.iface;
                     aparam.alias_ifs = NULL;
                     aparam.num_alias_ifs = 0;
-                    iface_enumerate(AF_LOCAL, &aparam, send_ra_to_aliases);
+                    iface_enumerate(AF_LOCAL, &aparam, (callback_t){.af_local=send_ra_to_aliases});
                     my_syslog(MS_DHCP | LOG_INFO, "RTR-ADVERT(%s) %s => %d alias(es)",
                               param.name, daemon->addrbuff, aparam.num_alias_ifs);
 
@@ -871,7 +871,7 @@ time_t periodic_ra(time_t now)
                            those. */
                         aparam.max_alias_ifs = aparam.num_alias_ifs;
                         aparam.num_alias_ifs = 0;
-                        iface_enumerate(AF_LOCAL, &aparam, send_ra_to_aliases);
+                        iface_enumerate(AF_LOCAL, &aparam, (callback_t){.af_local=send_ra_to_aliases});
                         for (; aparam.num_alias_ifs; aparam.num_alias_ifs--)
                           {
                             my_syslog(MS_DHCP | LOG_INFO, "RTR-ADVERT(%s) %s => i/f %d",
@@ -920,7 +920,7 @@ static int send_ra_to_aliases(int index, unsigned int type, char *mac, size_t ma
 
 static int iface_search(struct in6_addr *local,  int prefix,
 			int scope, int if_index, int flags, 
-			int preferred, int valid, void *vparam)
+			unsigned int preferred, unsigned int valid, void *vparam)
 {
   struct search_param *param = vparam;
   struct dhcp_context *context;
-- 
2.20.1