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.


=====
--- dnsmasq.h.orig      2024-02-13 08:49:15.000000000 -0500
+++ dnsmasq.h   2024-11-30 02:27:38.000000000 -0500
@@ -1659,7 +1659,13 @@
 #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
--- arp.c.orig  2024-02-13 08:49:15.000000000 -0500
+++ arp.c       2024-11-30 00:54:57.000000000 -0500
@@ -152,7 +152,7 @@
         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)
--- bpf.c.orig  2024-11-29 23:45:43.000000000 -0500
+++ bpf.c       2024-11-30 01:00:14.000000000 -0500
@@ -47,7 +47,7 @@
 
 #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 @@
       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 @@
 
   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 @@
                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 @@
                  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 @@
              /* 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 
--- dhcp.c.orig 2024-02-13 08:49:15.000000000 -0500
+++ dhcp.c      2024-11-30 00:55:40.000000000 -0500
@@ -317,7 +317,7 @@
          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 @@
       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
--- dhcp6.c.orig        2024-02-13 08:49:15.000000000 -0500
+++ dhcp6.c     2024-11-30 00:55:58.000000000 -0500
@@ -239,7 +239,7 @@
          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 @@
        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 @@
 
 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 @@
     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)
     {
--- lease.c.orig        2024-02-13 08:49:15.000000000 -0500
+++ lease.c     2024-11-30 00:56:09.000000000 -0500
@@ -407,7 +407,7 @@
 #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;
 
@@ -464,9 +464,9 @@
   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)
--- netlink.c.orig      2024-02-13 08:49:15.000000000 -0500
+++ netlink.c   2024-11-30 01:01:43.000000000 -0500
@@ -151,7 +151,7 @@
    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 @@
                      }
                    
                    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 @@
                      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 @@
 
            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 @@
              }
 
            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
--- network.c.orig      2024-02-13 08:49:15.000000000 -0500
+++ network.c   2024-11-30 00:56:34.000000000 -0500
@@ -596,7 +596,7 @@
 
 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 @@
 
   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;
     }
--- radv.c.orig 2024-02-13 08:49:15.000000000 -0500
+++ radv.c      2024-11-30 00:56:52.000000000 -0500
@@ -58,7 +58,7 @@
                        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 @@
 
   /* 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 @@
       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 @@
          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 @@
                     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 @@
                            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 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;
=====

_______________________________________________
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss

Reply via email to