2 * dhcpcd - DHCP client daemon
3 * Copyright (c) 2006-2009 Roy Marples <roy@marples.name>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include <sys/types.h>
29 #include <sys/ioctl.h>
30 #include <sys/param.h>
31 #include <sys/socket.h>
34 #include <arpa/inet.h>
36 #include <net/if_arp.h>
38 # include <net/if_dl.h>
39 # include <net/if_types.h>
41 #include <netinet/in_systm.h>
42 #include <netinet/in.h>
43 #include <netinet/ip.h>
44 #define __FAVOR_BSD /* Nasty glibc hack so we can use BSD semantics for UDP */
45 #include <netinet/udp.h>
48 # include <netpacket/packet.h>
51 # include <net/if_media.h>
68 #include "if-options.h"
72 static char hwaddr_buffer
[(HWADDR_LEN
* 3) + 1];
74 int socket_afnet
= -1;
77 inet_ntocidr(struct in_addr address
)
80 uint32_t mask
= htonl(address
.s_addr
);
90 inet_cidrtoaddr(int cidr
, struct in_addr
*addr
)
94 if (cidr
< 1 || cidr
> 32) {
98 ocets
= (cidr
+ 7) / 8;
102 memset(&addr
->s_addr
, 255, (size_t)ocets
- 1);
103 memset((unsigned char *)&addr
->s_addr
+ (ocets
- 1),
104 (256 - (1 << (32 - cidr
) % 8)), 1);
111 get_netmask(uint32_t addr
)
120 return ntohl(IN_CLASSA_NET
);
122 return ntohl(IN_CLASSB_NET
);
124 return ntohl(IN_CLASSC_NET
);
130 hwaddr_ntoa(const unsigned char *hwaddr
, size_t hwlen
)
132 char *p
= hwaddr_buffer
;
135 for (i
= 0; i
< hwlen
&& i
< HWADDR_LEN
; i
++) {
138 p
+= snprintf(p
, 3, "%.2x", hwaddr
[i
]);
143 return hwaddr_buffer
;
147 hwaddr_aton(unsigned char *buffer
, const char *addr
)
150 const char *p
= addr
;
151 unsigned char *bp
= buffer
;
158 /* Ensure that digits are hex */
159 if (isxdigit((unsigned char)c
[0]) == 0 ||
160 isxdigit((unsigned char)c
[1]) == 0)
165 /* We should have at least two entries 00:01 */
166 if (len
== 0 && *p
== '\0') {
170 /* Ensure that next data is EOL or a seperator with data */
171 if (!(*p
== '\0' || (*p
== ':' && *(p
+ 1) != '\0'))) {
178 *bp
++ = (unsigned char)strtol(c
, NULL
, 16);
185 init_interface(const char *ifname
)
188 struct interface
*iface
= NULL
;
190 memset(&ifr
, 0, sizeof(ifr
));
191 strlcpy(ifr
.ifr_name
, ifname
, sizeof(ifr
.ifr_name
));
192 if (ioctl(socket_afnet
, SIOCGIFFLAGS
, &ifr
) == -1)
195 iface
= xzalloc(sizeof(*iface
));
196 strlcpy(iface
->name
, ifname
, sizeof(iface
->name
));
197 iface
->flags
= ifr
.ifr_flags
;
198 /* We reserve the 100 range for virtual interfaces, if and when
199 * we can work them out. */
200 iface
->metric
= 200 + if_nametoindex(iface
->name
);
201 if (getifssid(ifname
, iface
->ssid
) != -1) {
203 iface
->metric
+= 100;
206 if (ioctl(socket_afnet
, SIOCGIFMTU
, &ifr
) == -1)
208 /* Ensure that the MTU is big enough for DHCP */
209 if (ifr
.ifr_mtu
< MTU_MIN
) {
210 ifr
.ifr_mtu
= MTU_MIN
;
211 strlcpy(ifr
.ifr_name
, ifname
, sizeof(ifr
.ifr_name
));
212 if (ioctl(socket_afnet
, SIOCSIFMTU
, &ifr
) == -1)
216 snprintf(iface
->leasefile
, sizeof(iface
->leasefile
),
218 /* 0 is a valid fd, so init to -1 */
232 free_interface(struct interface
*iface
)
237 free_options(iface
->state
->options
);
238 free(iface
->state
->old
);
239 free(iface
->state
->new);
240 free(iface
->state
->offer
);
243 free(iface
->clientid
);
248 carrier_status(struct interface
*iface
)
253 struct ifmediareq ifmr
;
259 memset(&ifr
, 0, sizeof(ifr
));
260 strlcpy(ifr
.ifr_name
, iface
->name
, sizeof(ifr
.ifr_name
));
262 /* We can only test the real interface up */
263 if ((p
= strchr(ifr
.ifr_name
, ':')))
267 if (ioctl(socket_afnet
, SIOCGIFFLAGS
, &ifr
) == -1)
269 iface
->flags
= ifr
.ifr_flags
;
273 memset(&ifmr
, 0, sizeof(ifmr
));
274 strlcpy(ifmr
.ifm_name
, iface
->name
, sizeof(ifmr
.ifm_name
));
275 if (ioctl(socket_afnet
, SIOCGIFMEDIA
, &ifmr
) != -1 &&
276 ifmr
.ifm_status
& IFM_AVALID
)
277 ret
= (ifmr
.ifm_status
& IFM_ACTIVE
) ? 1 : 0;
280 ret
= (ifr
.ifr_flags
& IFF_RUNNING
) ? 1 : 0;
285 up_interface(struct interface
*iface
)
293 memset(&ifr
, 0, sizeof(ifr
));
294 strlcpy(ifr
.ifr_name
, iface
->name
, sizeof(ifr
.ifr_name
));
296 /* We can only bring the real interface up */
297 if ((p
= strchr(ifr
.ifr_name
, ':')))
300 if (ioctl(socket_afnet
, SIOCGIFFLAGS
, &ifr
) == 0) {
301 if ((ifr
.ifr_flags
& IFF_UP
))
304 ifr
.ifr_flags
|= IFF_UP
;
305 if (ioctl(socket_afnet
, SIOCSIFFLAGS
, &ifr
) == 0)
308 iface
->flags
= ifr
.ifr_flags
;
314 discover_interfaces(int argc
, char * const *argv
)
316 struct ifaddrs
*ifaddrs
, *ifa
;
319 struct interface
*ifp
, *ifs
, *ifl
;
321 char ifn
[IF_NAMESIZE
];
324 const struct sockaddr_dl
*sdl
;
326 const struct sockaddr_ll
*sll
;
329 if (getifaddrs(&ifaddrs
) == -1)
333 for (ifa
= ifaddrs
; ifa
; ifa
= ifa
->ifa_next
) {
334 if (ifa
->ifa_addr
!= NULL
) {
336 if (ifa
->ifa_addr
->sa_family
!= AF_LINK
)
339 if (ifa
->ifa_addr
->sa_family
!= AF_PACKET
)
344 /* It's possible for an interface to have >1 AF_LINK.
345 * For our purposes, we use the first one. */
346 for (ifp
= ifs
; ifp
; ifp
= ifp
->next
)
347 if (strcmp(ifp
->name
, ifa
->ifa_name
) == 0)
352 for (i
= 0; i
< argc
; i
++) {
354 /* Check the real interface name */
355 strlcpy(ifn
, argv
[i
], sizeof(ifn
));
356 p
= strchr(ifn
, ':');
359 if (strcmp(ifn
, ifa
->ifa_name
) == 0)
362 if (strcmp(argv
[i
], ifa
->ifa_name
) == 0)
370 /* -1 means we're discovering against a specific
371 * interface, but we still need the below rules
373 if (argc
== -1 && strcmp(argv
[0], ifa
->ifa_name
) != 0)
375 for (i
= 0; i
< ifdc
; i
++)
376 if (!fnmatch(ifdv
[i
], ifa
->ifa_name
, 0))
380 for (i
= 0; i
< ifac
; i
++)
381 if (!fnmatch(ifav
[i
], ifa
->ifa_name
, 0))
383 if (ifac
&& i
== ifac
)
387 if ((ifp
= init_interface(p
)) == NULL
)
390 /* Bring the interface up if not already */
391 if (!(ifp
->flags
& IFF_UP
)
393 && carrier_status(ifp
) != -1
397 if (up_interface(ifp
) == 0)
398 options
|= DHCPCD_WAITUP
;
400 syslog(LOG_ERR
, "%s: up_interface: %m", ifp
->name
);
403 /* Don't allow loopback unless explicit */
404 if (ifp
->flags
& IFF_LOOPBACK
) {
405 if (argc
== 0 && ifac
== 0) {
409 } else if (ifa
->ifa_addr
!= NULL
) {
411 sdl
= (const struct sockaddr_dl
*)(void *)ifa
->ifa_addr
;
412 switch(sdl
->sdl_type
) {
414 ifp
->family
= ARPHRD_ETHER
;
417 ifp
->family
= ARPHRD_IEEE1394
;
420 ifp
->hwlen
= sdl
->sdl_alen
;
422 # define CLLADDR(s) ((const char *)((s)->sdl_data + (s)->sdl_nlen))
424 memcpy(ifp
->hwaddr
, CLLADDR(sdl
), ifp
->hwlen
);
426 sll
= (const struct sockaddr_ll
*)(void *)ifa
->ifa_addr
;
427 ifp
->family
= sll
->sll_hatype
;
428 ifp
->hwlen
= sll
->sll_halen
;
430 memcpy(ifp
->hwaddr
, sll
->sll_addr
, ifp
->hwlen
);
434 /* We only work on ethernet by default */
435 if (!(ifp
->flags
& IFF_POINTOPOINT
) &&
436 ifp
->family
!= ARPHRD_ETHER
)
438 if (argc
== 0 && ifac
== 0) {
442 if (ifp
->family
!= ARPHRD_IEEE1394
)
444 "%s: unknown hardware family", p
);
452 freeifaddrs(ifaddrs
);
457 do_address(const char *ifname
,
458 struct in_addr
*addr
, struct in_addr
*net
, struct in_addr
*dst
, int act
)
460 struct ifaddrs
*ifaddrs
, *ifa
;
461 const struct sockaddr_in
*a
, *n
, *d
;
464 if (getifaddrs(&ifaddrs
) == -1)
468 for (ifa
= ifaddrs
; ifa
; ifa
= ifa
->ifa_next
) {
469 if (ifa
->ifa_addr
== NULL
||
470 ifa
->ifa_addr
->sa_family
!= AF_INET
||
471 strcmp(ifa
->ifa_name
, ifname
) != 0)
473 a
= (const struct sockaddr_in
*)(void *)ifa
->ifa_addr
;
474 n
= (const struct sockaddr_in
*)(void *)ifa
->ifa_netmask
;
475 if (ifa
->ifa_flags
& IFF_POINTOPOINT
)
476 d
= (const struct sockaddr_in
*)(void *)
481 addr
->s_addr
= a
->sin_addr
.s_addr
;
482 net
->s_addr
= n
->sin_addr
.s_addr
;
483 if (dst
&& ifa
->ifa_flags
& IFF_POINTOPOINT
)
484 dst
->s_addr
= d
->sin_addr
.s_addr
;
488 if (addr
->s_addr
== a
->sin_addr
.s_addr
&&
489 (net
== NULL
|| net
->s_addr
== n
->sin_addr
.s_addr
))
495 freeifaddrs(ifaddrs
);
500 do_mtu(const char *ifname
, short int mtu
)
505 memset(&ifr
, 0, sizeof(ifr
));
506 strlcpy(ifr
.ifr_name
, ifname
, sizeof(ifr
.ifr_name
));
508 r
= ioctl(socket_afnet
, mtu
? SIOCSIFMTU
: SIOCGIFMTU
, &ifr
);
515 free_routes(struct rt
*routes
)
527 open_udp_socket(struct interface
*iface
)
530 struct sockaddr_in sin
;
532 #ifdef SO_BINDTODEVICE
537 if ((s
= socket(PF_INET
, SOCK_DGRAM
, IPPROTO_UDP
)) == -1)
541 if (setsockopt(s
, SOL_SOCKET
, SO_REUSEADDR
, &n
, sizeof(n
)) == -1)
543 #ifdef SO_BINDTODEVICE
544 memset(&ifr
, 0, sizeof(ifr
));
545 strlcpy(ifr
.ifr_name
, iface
->name
, sizeof(ifr
.ifr_name
));
546 /* We can only bind to the real device */
547 p
= strchr(ifr
.ifr_name
, ':');
550 if (setsockopt(s
, SOL_SOCKET
, SO_BINDTODEVICE
, &ifr
,
554 /* As we don't use this socket for receiving, set the
555 * receive buffer to 1 */
557 if (setsockopt(s
, SOL_SOCKET
, SO_RCVBUF
, &n
, sizeof(n
)) == -1)
559 memset(&sin
, 0, sizeof(sin
));
560 sin
.sin_family
= AF_INET
;
561 sin
.sin_port
= htons(DHCP_CLIENT_PORT
);
562 sin
.sin_addr
.s_addr
= iface
->addr
.s_addr
;
563 if (bind(s
, (struct sockaddr
*)&sin
, sizeof(sin
)) == -1)
576 send_packet(const struct interface
*iface
, struct in_addr to
,
577 const uint8_t *data
, ssize_t len
)
579 struct sockaddr_in sin
;
581 memset(&sin
, 0, sizeof(sin
));
582 sin
.sin_family
= AF_INET
;
583 sin
.sin_addr
.s_addr
= to
.s_addr
;
584 sin
.sin_port
= htons(DHCP_SERVER_PORT
);
585 return sendto(iface
->udp_fd
, data
, len
, 0,
586 (struct sockaddr
*)&sin
, sizeof(sin
));
589 struct udp_dhcp_packet
593 struct dhcp_message dhcp
;
595 const size_t udp_dhcp_len
= sizeof(struct udp_dhcp_packet
);
598 checksum(const void *data
, uint16_t len
)
600 const uint8_t *addr
= data
;
604 sum
+= addr
[0] * 256 + addr
[1];
612 sum
= (sum
>> 16) + (sum
& 0xffff);
621 make_udp_packet(uint8_t **packet
, const uint8_t *data
, size_t length
,
622 struct in_addr source
, struct in_addr dest
)
624 struct udp_dhcp_packet
*udpp
;
628 udpp
= xzalloc(sizeof(*udpp
));
632 /* OK, this is important :)
633 * We copy the data to our packet and then create a small part of the
634 * ip structure and an invalid ip_len (basically udp length).
635 * We then fill the udp structure and put the checksum
636 * of the whole packet into the udp checksum.
637 * Finally we complete the ip structure and ip checksum.
638 * If we don't do the ordering like so then the udp checksum will be
639 * broken, so find another way of doing it! */
641 memcpy(&udpp
->dhcp
, data
, length
);
643 ip
->ip_p
= IPPROTO_UDP
;
644 ip
->ip_src
.s_addr
= source
.s_addr
;
645 if (dest
.s_addr
== 0)
646 ip
->ip_dst
.s_addr
= INADDR_BROADCAST
;
648 ip
->ip_dst
.s_addr
= dest
.s_addr
;
650 udp
->uh_sport
= htons(DHCP_CLIENT_PORT
);
651 udp
->uh_dport
= htons(DHCP_SERVER_PORT
);
652 udp
->uh_ulen
= htons(sizeof(*udp
) + length
);
653 ip
->ip_len
= udp
->uh_ulen
;
654 udp
->uh_sum
= checksum(udpp
, sizeof(*udpp
));
656 ip
->ip_v
= IPVERSION
;
659 ip
->ip_tos
= IPTOS_LOWDELAY
;
660 ip
->ip_len
= htons (sizeof(*ip
) + sizeof(*udp
) + length
);
662 ip
->ip_off
= htons(IP_DF
); /* Don't fragment */
663 ip
->ip_ttl
= IPDEFTTL
;
665 ip
->ip_sum
= checksum(ip
, sizeof(*ip
));
667 *packet
= (uint8_t *)udpp
;
668 return sizeof(*ip
) + sizeof(*udp
) + length
;
672 get_udp_data(const uint8_t **data
, const uint8_t *udp
)
674 struct udp_dhcp_packet packet
;
676 memcpy(&packet
, udp
, sizeof(packet
));
677 *data
= udp
+ offsetof(struct udp_dhcp_packet
, dhcp
);
678 return ntohs(packet
.ip
.ip_len
) -
684 valid_udp_packet(const uint8_t *data
, size_t data_len
, struct in_addr
*from
)
686 struct udp_dhcp_packet packet
;
687 uint16_t bytes
, udpsum
;
689 if (data_len
< sizeof(packet
.ip
)) {
691 from
->s_addr
= INADDR_ANY
;
695 memcpy(&packet
, data
, MIN(data_len
, sizeof(packet
)));
697 from
->s_addr
= packet
.ip
.ip_src
.s_addr
;
698 if (data_len
> sizeof(packet
)) {
702 if (checksum(&packet
.ip
, sizeof(packet
.ip
)) != 0) {
707 bytes
= ntohs(packet
.ip
.ip_len
);
708 if (data_len
< bytes
) {
712 udpsum
= packet
.udp
.uh_sum
;
713 packet
.udp
.uh_sum
= 0;
716 packet
.ip
.ip_tos
= 0;
717 packet
.ip
.ip_len
= packet
.udp
.uh_ulen
;
719 packet
.ip
.ip_off
= 0;
720 packet
.ip
.ip_ttl
= 0;
721 packet
.ip
.ip_sum
= 0;
722 if (udpsum
&& checksum(&packet
, bytes
) != udpsum
) {