1 $DragonFly: src/sbin/dhclient/common/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
11 struct interface_info *interfaces, *dummy_interfaces, *fallback_interface;
14 struct interface_info *tmp, *ip;
15 struct interface_info *last, *next;
20 + struct ifaddrs *ifap, *ifa;
22 int address_count = 0;
23 struct subnet *subnet;
25 if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
26 log_fatal ("Can't create addrlist socket");
28 - /* Get the interface configuration information... */
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.
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. */
40 - ic.ifc_ifcu.ifcu_buf = (caddr_t)NULL;
42 - /* otherwise, we just feed it a starting size, and it'll tell us if
45 - ic.ifc_len = sizeof buf;
46 - ic.ifc_ifcu.ifcu_buf = (caddr_t)buf;
50 - i = ioctl(sock, SIOCGIFCONF, &ic);
53 - log_fatal ("ioctl: SIOCGIFCONF: %m");
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;
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
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.");
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;
84 /* If we already have a list of interfaces, and we're running as
85 a DHCP server, the interfaces were requested. */
88 ir = INTERFACE_REQUESTED;
90 + if (getifaddrs(&ifap) != 0)
91 + log_fatal ("getifaddrs failed");
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);
97 - if (ifp -> ifr_addr.sa_len > sizeof (struct sockaddr))
98 - i += (sizeof ifp -> ifr_name) + ifp -> ifr_addr.sa_len;
102 + for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
104 #ifdef ALIAS_NAMES_PERMUTED
105 - if ((s = strrchr (ifp -> ifr_name, ':'))) {
106 + if ((s = strrchr (ifa -> ifa_name, ':'))) {
111 #ifdef SKIP_DUMMY_INTERFACES
112 - if (!strncmp (ifp -> ifr_name, "dummy", 5))
113 + if (!strncmp (ifa -> ifa_name, "dummy", 5))
118 - /* See if this is the sort of interface we want to
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",
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))
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))
149 /* If there isn't already an interface by this name,
153 status = interface_allocate (&tmp, MDL);
154 if (status != ISC_R_SUCCESS)
155 log_fatal ("Error allocating interface %s: %s",
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 */
165 /* If we have the capability, extract link information
166 and record it in a linked list. */
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;
176 @@ -296,12 +226,11 @@
180 - if (ifp -> ifr_addr.sa_family == AF_INET) {
181 + if (ifa -> ifa_addr->sa_family == AF_INET) {
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));
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. */
196 - unsigned len = ((sizeof ifp -> ifr_name) +
197 - ifp -> ifr_addr.sa_len);
199 - unsigned len = sizeof *ifp;
202 + int len = (IFNAMSIZ +
203 + ifa -> ifa_addr->sa_len);
204 tif = (struct ifreq *)dmalloc (len, MDL);
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);
212 tmp -> primary_address = foo.sin_addr;
218 - /* If we allocated a buffer, free it. */
219 - if (ic.ifc_ifcu.ifcu_buf != buf)
220 - dfree (ic.ifc_ifcu.ifcu_buf, MDL);
222 #if defined (LINUX_SLASHPROC_DISCOVERY)
223 /* On Linux, interfaces that don't have IP addresses don't
225 be able to configure, we can quit now. */
226 if (state == DISCOVER_UNCONFIGURED) {
238 if (state == DISCOVER_SERVER && wifcount == 0) {