Merge from vendor branch LIBARCHIVE:
[dragonfly.git] / sbin / dhclient / common / discover.c.patch
1 $DragonFly: src/sbin/dhclient/common/Attic/discover.c.patch,v 1.1 2005/01/04 19:58:54 joerg Exp $
2 --- discover.c.orig     2004-06-10 19:59:16.000000000 +0200
3 +++ discover.c  2004-06-24 16:36:10.000000000 +0200
4 @@ -38,6 +38,7 @@
5  #endif /* not lint */
6  
7  #include "dhcpd.h"
8 +#include <ifaddrs.h>
9  #include <sys/ioctl.h>
10  
11  struct interface_info *interfaces, *dummy_interfaces, *fallback_interface;
12 @@ -126,10 +127,7 @@
13  {
14         struct interface_info *tmp, *ip;
15         struct interface_info *last, *next;
16 -       char buf [2048];
17 -       struct ifconf ic;
18 -       struct ifreq ifr;
19 -       int i;
20 +       struct ifaddrs *ifap, *ifa;
21         int sock;
22         int address_count = 0;
23         struct subnet *subnet;
24 @@ -148,61 +146,6 @@
25         if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
26                 log_fatal ("Can't create addrlist socket");
27  
28 -       /* Get the interface configuration information... */
29 -
30 -#ifdef SIOCGIFCONF_ZERO_PROBE
31 -       /* linux will only tell us how long a buffer it wants if we give it
32 -        * a null buffer first. So, do a dry run to figure out the length.
33 -        * 
34 -        * XXX this code is duplicated from below because trying to fold
35 -        * the logic into the if statement and goto resulted in excesssive
36 -        * obfuscation. The intent is that unless you run Linux you shouldn't
37 -        * have to deal with this. */
38 -
39 -       ic.ifc_len = 0;
40 -       ic.ifc_ifcu.ifcu_buf = (caddr_t)NULL;
41 -#else
42 -       /* otherwise, we just feed it a starting size, and it'll tell us if
43 -        * it needs more */
44 -
45 -       ic.ifc_len = sizeof buf;
46 -       ic.ifc_ifcu.ifcu_buf = (caddr_t)buf;
47 -#endif
48 -
49 -      gifconf_again:
50 -       i = ioctl(sock, SIOCGIFCONF, &ic);
51 -
52 -       if (i < 0)
53 -               log_fatal ("ioctl: SIOCGIFCONF: %m");
54 -
55 -#ifdef SIOCGIFCONF_ZERO_PROBE
56 -       /* Workaround for SIOCGIFCONF bug on some Linux versions. */
57 -       if (ic.ifc_ifcu.ifcu_buf == 0 && ic.ifc_len == 0) {
58 -               ic.ifc_len = sizeof buf;
59 -               ic.ifc_ifcu.ifcu_buf = (caddr_t)buf;
60 -               goto gifconf_again;
61 -       }
62 -#endif
63 -
64 -       /* If the SIOCGIFCONF resulted in more data than would fit in
65 -          a buffer, allocate a bigger buffer. */
66 -       if ((ic.ifc_ifcu.ifcu_buf == buf 
67 -#ifdef SIOCGIFCONF_ZERO_PROBE
68 -            || ic.ifc_ifcu.ifcu_buf == 0
69 -#endif
70 -               ) && ic.ifc_len > sizeof buf) {
71 -               ic.ifc_ifcu.ifcu_buf = dmalloc ((size_t)ic.ifc_len, MDL);
72 -               if (!ic.ifc_ifcu.ifcu_buf)
73 -                       log_fatal ("Can't allocate SIOCGIFCONF buffer.");
74 -               goto gifconf_again;
75 -#ifdef SIOCGIFCONF_ZERO_PROBE
76 -       } else if (ic.ifc_ifcu.ifcu_buf == 0) {
77 -               ic.ifc_ifcu.ifcu_buf = (caddr_t)buf;
78 -               ic.ifc_len = sizeof buf;
79 -               goto gifconf_again;
80 -#endif
81 -       }
82 -
83                 
84         /* If we already have a list of interfaces, and we're running as
85            a DHCP server, the interfaces were requested. */
86 @@ -215,51 +158,38 @@
87         else
88                 ir = INTERFACE_REQUESTED;
89  
90 +       if (getifaddrs(&ifap) != 0)
91 +               log_fatal ("getifaddrs failed");
92 +
93         /* Cycle through the list of interfaces looking for IP addresses. */
94 -       for (i = 0; i < ic.ifc_len;) {
95 -               struct ifreq *ifp = (struct ifreq *)((caddr_t)ic.ifc_req + i);
96 -#ifdef HAVE_SA_LEN
97 -               if (ifp -> ifr_addr.sa_len > sizeof (struct sockaddr))
98 -                       i += (sizeof ifp -> ifr_name) + ifp -> ifr_addr.sa_len;
99 -               else
100 -#endif
101 -                       i += sizeof *ifp;
102 +       for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
103  
104  #ifdef ALIAS_NAMES_PERMUTED
105 -               if ((s = strrchr (ifp -> ifr_name, ':'))) {
106 +               if ((s = strrchr (ifa -> ifa_name, ':'))) {
107                         *s = 0;
108                 }
109  #endif
110  
111  #ifdef SKIP_DUMMY_INTERFACES
112 -               if (!strncmp (ifp -> ifr_name, "dummy", 5))
113 +               if (!strncmp (ifa -> ifa_name, "dummy", 5))
114                         continue;
115  #endif
116  
117 -
118 -               /* See if this is the sort of interface we want to
119 -                  deal with. */
120 -               strcpy (ifr.ifr_name, ifp -> ifr_name);
121 -               if (ioctl (sock, SIOCGIFFLAGS, &ifr) < 0)
122 -                       log_fatal ("Can't get interface flags for %s: %m",
123 -                              ifr.ifr_name);
124 -
125                 /* See if we've seen an interface that matches this one. */
126                 for (tmp = interfaces; tmp; tmp = tmp -> next)
127 -                       if (!strcmp (tmp -> name, ifp -> ifr_name))
128 +                       if (!strcmp (tmp -> name, ifa -> ifa_name))
129                                 break;
130  
131 -               /* Skip non broadcast interfaces (plus loopback and
132 -                  point-to-point in case an OS incorrectly marks them
133 -                  as broadcast). Also skip down interfaces unless we're
134 +               /* See if this is the sort of interface we want to
135 +                  deal with.  Skip loopback, point-to-point and down
136 +                  interfaces, except don't skip down interfaces if we're
137                    trying to get a list of configurable interfaces. */
138 -               if (((!(ifr.ifr_flags & IFF_BROADCAST) ||
139 -                     ifr.ifr_flags & IFF_LOOPBACK ||
140 -                     ifr.ifr_flags & IFF_POINTOPOINT) && !tmp) ||
141 -                   (!(ifr.ifr_flags & IFF_UP) &&
142 +               if ((ifa->ifa_flags & IFF_LOOPBACK) ||
143 +                    (ifa->ifa_flags & IFF_POINTOPOINT) ||
144 +                    (!(ifa->ifa_flags & IFF_UP) &&
145                      state != DISCOVER_UNCONFIGURED))
146                         continue;
147 -               
148 +
149                 /* If there isn't already an interface by this name,
150                    allocate one. */
151                 if (!tmp) {
152 @@ -267,9 +197,9 @@
153                         status = interface_allocate (&tmp, MDL);
154                         if (status != ISC_R_SUCCESS)
155                                 log_fatal ("Error allocating interface %s: %s",
156 -                                          ifp -> ifr_name,
157 +                                          ifa -> ifa_name,
158                                            isc_result_totext (status));
159 -                       strcpy (tmp -> name, ifp -> ifr_name);
160 +                       strcpy (tmp -> name, ifa -> ifa_name);
161                         interface_snorf (tmp, ir);
162                         interface_dereference (&tmp, MDL);
163                         tmp = interfaces; /* XXX */
164 @@ -281,9 +211,9 @@
165                 /* If we have the capability, extract link information
166                    and record it in a linked list. */
167  #ifdef HAVE_AF_LINK
168 -               if (ifp -> ifr_addr.sa_family == AF_LINK) {
169 +               if (ifa -> ifa_addr->sa_family == AF_LINK) {
170                         struct sockaddr_dl *foo = ((struct sockaddr_dl *)
171 -                                                  (&ifp -> ifr_addr));
172 +                                                  (ifa -> ifa_addr));
173  #if defined (HAVE_SIN_LEN)
174                         tmp -> hw_address.hlen = foo -> sdl_alen;
175  #else
176 @@ -296,12 +226,11 @@
177                 } else
178  #endif /* AF_LINK */
179  
180 -               if (ifp -> ifr_addr.sa_family == AF_INET) {
181 +               if (ifa -> ifa_addr->sa_family == AF_INET) {
182                         struct iaddr addr;
183  
184                         /* Get a pointer to the address... */
185 -                       memcpy (&foo, &ifp -> ifr_addr,
186 -                               sizeof ifp -> ifr_addr);
187 +                       bcopy(ifa->ifa_addr, &foo, sizeof(foo));
188  
189                         /* We don't want the loopback interface. */
190                         if (foo.sin_addr.s_addr == htonl (INADDR_LOOPBACK) &&
191 @@ -314,16 +243,15 @@
192                            found, keep a pointer to ifreq structure in
193                            which we found it. */
194                         if (!tmp -> ifp) {
195 -#ifdef HAVE_SA_LEN
196 -                               unsigned len = ((sizeof ifp -> ifr_name) +
197 -                                               ifp -> ifr_addr.sa_len);
198 -#else
199 -                               unsigned len = sizeof *ifp;
200 -#endif
201 +
202 +                               int len = (IFNAMSIZ +
203 +                                       ifa -> ifa_addr->sa_len);
204                                 tif = (struct ifreq *)dmalloc (len, MDL);
205                                 if (!tif)
206                                         log_fatal ("no space for ifp.");
207 -                               memcpy (tif, ifp, len);
208 +                               strlcpy(tif->ifr_name, ifa->ifa_name, IFNAMSIZ);
209 +                               memcpy(&tif->ifr_addr, ifa->ifa_addr,
210 +                                       ifa->ifa_addr->sa_len);
211                                 tmp -> ifp = tif;
212                                 tmp -> primary_address = foo.sin_addr;
213                         }
214 @@ -337,9 +265,6 @@
215                 }
216         }
217  
218 -       /* If we allocated a buffer, free it. */
219 -       if (ic.ifc_ifcu.ifcu_buf != buf)
220 -               dfree (ic.ifc_ifcu.ifcu_buf, MDL);
221  
222  #if defined (LINUX_SLASHPROC_DISCOVERY)
223         /* On Linux, interfaces that don't have IP addresses don't
224 @@ -520,6 +445,7 @@
225            be able to configure, we can quit now. */
226         if (state == DISCOVER_UNCONFIGURED) {
227                 close (sock);
228 +               freeifaddrs(ifap);
229                 return;
230         }
231  
232 @@ -665,6 +591,7 @@
233         }
234  
235         close (sock);
236 +       freeifaddrs(ifap);
237  
238         if (state == DISCOVER_SERVER && wifcount == 0) {
239                 log_info ("%s", "");