1/*
2 * dhcpcd - DHCP client daemon
3 * Copyright (c) 2006-2011 Roy Marples <roy@marples.name>
4 * All rights reserved
5
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
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.
14 *
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
25 * SUCH DAMAGE.
26 */
27
28#include <asm/types.h> /* Needed for 2.4 kernels */
29
30#include <sys/types.h>
31#include <sys/socket.h>
32#include <sys/ioctl.h>
33#include <sys/param.h>
34
35#include <linux/netlink.h>
36#include <linux/rtnetlink.h>
37
38/* Support older kernels */
39#ifndef IFLA_WIRELESS
40# define IFLA_WIRELESS (IFLA_MASTER + 1)
41#endif
42
43#include <errno.h>
44#include <ctype.h>
45#include <stddef.h>
46#include <stdio.h>
47#include <stdlib.h>
48#include <string.h>
49#include <unistd.h>
50
51#include "config.h"
52#include "common.h"
53#include "configure.h"
54#include "dhcp.h"
55#include "net.h"
56
57/* ANDROID change, moved this below all includes. */
58/* For some reason, glibc doesn't include newer flags from linux/if.h
59 * However, we cannot include linux/if.h directly as it conflicts
60 * with the glibc version. D'oh! */
61#ifndef IFF_LOWER_UP
62#define IFF_LOWER_UP	0x10000		/* driver signals L1 up		*/
63#endif
64/* End of ANDROID change */
65
66static int sock_fd;
67static struct sockaddr_nl sock_nl;
68
69int
70if_init(struct interface *iface)
71{
72	char path[PATH_MAX];
73	FILE *fp;
74	int n;
75
76	/* We enable promote_secondaries so that we can do this
77	 * add 192.168.1.2/24
78	 * add 192.168.1.3/24
79	 * del 192.168.1.2/24
80	 * and the subnet mask moves onto 192.168.1.3/24
81	 * This matches the behaviour of BSD which makes coding dhcpcd
82	 * a little easier as there's just one behaviour. */
83	snprintf(path, sizeof(path),
84	    "/proc/sys/net/ipv4/conf/%s/promote_secondaries",
85	    iface->name);
86
87	fp = fopen(path, "w");
88	if (fp == NULL)
89		return errno == ENOENT ? 0 : -1;
90	n = fprintf(fp, "1");
91	fclose(fp);
92	return n == -1 ? -1 : 0;
93}
94
95int
96if_conf(struct interface *iface)
97{
98	char path[PATH_MAX], buf[1];
99	FILE *fp;
100
101	/* Some qeth setups require the use of the broadcast flag. */
102	snprintf(path, sizeof(path),
103	    "/sys/class/net/%s/device/layer2",
104	    iface->name);
105
106	fp = fopen(path, "r");
107	if (fp == NULL)
108		return errno == ENOENT ? 0 : -1;
109	if (fgets(buf, sizeof(buf), fp) != NULL && buf[0] == '0')
110		iface->state->options->options |= DHCPCD_BROADCAST;
111	fclose(fp);
112	return 0;
113}
114
115static int
116_open_link_socket(struct sockaddr_nl *nl)
117{
118	int fd;
119
120	if ((fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1)
121		return -1;
122	nl->nl_family = AF_NETLINK;
123	if (bind(fd, (struct sockaddr *)nl, sizeof(*nl)) == -1)
124		return -1;
125	set_cloexec(fd);
126	return fd;
127}
128
129int
130init_sockets(void)
131{
132	if ((socket_afnet = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
133		return -1;
134	set_cloexec(socket_afnet);
135	sock_fd = _open_link_socket(&sock_nl);
136	set_cloexec(sock_fd);
137	return sock_fd;
138}
139
140int
141open_link_socket(void)
142{
143	struct sockaddr_nl snl;
144
145	memset(&snl, 0, sizeof(snl));
146	snl.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR;
147	return _open_link_socket(&snl);
148}
149
150static int
151get_netlink(int fd, int flags,
152    int (*callback)(struct nlmsghdr *))
153{
154	char *buf = NULL, *nbuf;
155	ssize_t buflen = 0, bytes;
156	struct nlmsghdr *nlm;
157	int r = -1;
158
159	for (;;) {
160		bytes = recv(fd, NULL, 0,
161		    flags | MSG_PEEK | MSG_DONTWAIT | MSG_TRUNC);
162		if (bytes == -1) {
163			if (errno == EAGAIN) {
164				r = 0;
165				goto eexit;
166			}
167			if (errno == EINTR)
168				continue;
169			goto eexit;
170		} else if (bytes == buflen) {
171			/* Support kernels older than 2.6.22 */
172			if (bytes == 0)
173				bytes = 512;
174			else
175				bytes *= 2;
176		}
177		if (buflen < bytes) {
178			/* Alloc 1 more so we work with older kernels */
179			buflen = bytes + 1;
180			nbuf = realloc(buf, buflen);
181			if (nbuf == NULL)
182				goto eexit;
183			buf = nbuf;
184		}
185		bytes = recv(fd, buf, buflen, flags);
186		if (bytes == -1) {
187			if (errno == EAGAIN) {
188				r = 0;
189				goto eexit;
190			}
191			if (errno == EINTR)
192				continue;
193			goto eexit;
194		}
195		for (nlm = (struct nlmsghdr *)buf;
196		     NLMSG_OK(nlm, (size_t)bytes);
197		     nlm = NLMSG_NEXT(nlm, bytes))
198		{
199			r = callback(nlm);
200			if (r != 0)
201				goto eexit;
202		}
203	}
204
205eexit:
206	free(buf);
207	return r;
208}
209
210static int
211err_netlink(struct nlmsghdr *nlm)
212{
213	struct nlmsgerr *err;
214	int l;
215
216	if (nlm->nlmsg_type != NLMSG_ERROR)
217		return 0;
218	l = nlm->nlmsg_len - sizeof(*nlm);
219	if ((size_t)l < sizeof(*err)) {
220		errno = EBADMSG;
221		return -1;
222	}
223	err = (struct nlmsgerr *)NLMSG_DATA(nlm);
224	if (err->error == 0)
225		return l;
226	errno = -err->error;
227	return -1;
228}
229
230static int
231link_route(struct nlmsghdr *nlm)
232{
233	int len, idx, metric;
234	struct rtattr *rta;
235	struct rtmsg *rtm;
236	struct rt rt;
237	char ifn[IF_NAMESIZE + 1];
238
239	if (nlm->nlmsg_type != RTM_DELROUTE)
240		return 0;
241
242	len = nlm->nlmsg_len - sizeof(*nlm);
243	if ((size_t)len < sizeof(*rtm)) {
244		errno = EBADMSG;
245		return -1;
246	}
247	rtm = NLMSG_DATA(nlm);
248	if (rtm->rtm_type != RTN_UNICAST ||
249	    rtm->rtm_table != RT_TABLE_MAIN ||
250	    rtm->rtm_family != AF_INET ||
251	    nlm->nlmsg_pid == (uint32_t)getpid())
252		return 1;
253	rta = (struct rtattr *) ((char *)rtm + NLMSG_ALIGN(sizeof(*rtm)));
254	len = NLMSG_PAYLOAD(nlm, sizeof(*rtm));
255	rt.iface = NULL;
256	rt.dest.s_addr = INADDR_ANY;
257	rt.net.s_addr = INADDR_ANY;
258	rt.gate.s_addr = INADDR_ANY;
259	rt.next = NULL;
260	metric = 0;
261	while (RTA_OK(rta, len)) {
262		switch (rta->rta_type) {
263		case RTA_DST:
264			memcpy(&rt.dest.s_addr, RTA_DATA(rta),
265			    sizeof(rt.dest.s_addr));
266			break;
267		case RTA_GATEWAY:
268			memcpy(&rt.gate.s_addr, RTA_DATA(rta),
269			    sizeof(rt.gate.s_addr));
270			break;
271		case RTA_OIF:
272			idx = *(int *)RTA_DATA(rta);
273			if (if_indextoname(idx, ifn))
274				rt.iface = find_interface(ifn);
275			break;
276		case RTA_PRIORITY:
277			metric = *(int *)RTA_DATA(rta);
278			break;
279		}
280		rta = RTA_NEXT(rta, len);
281	}
282	if (rt.iface != NULL) {
283		if (metric == rt.iface->metric) {
284			inet_cidrtoaddr(rtm->rtm_dst_len, &rt.net);
285			route_deleted(&rt);
286		}
287	}
288	return 1;
289}
290
291static int
292link_addr(struct nlmsghdr *nlm)
293{
294	int len;
295	struct rtattr *rta;
296	struct ifaddrmsg *ifa;
297	struct in_addr addr, net, dest;
298	char ifn[IF_NAMESIZE + 1];
299	struct interface *iface;
300
301	if (nlm->nlmsg_type != RTM_DELADDR && nlm->nlmsg_type != RTM_NEWADDR)
302		return 0;
303
304	len = nlm->nlmsg_len - sizeof(*nlm);
305	if ((size_t)len < sizeof(*ifa)) {
306		errno = EBADMSG;
307		return -1;
308	}
309	if (nlm->nlmsg_pid == (uint32_t)getpid())
310		return 1;
311	ifa = NLMSG_DATA(nlm);
312	if (if_indextoname(ifa->ifa_index, ifn) == NULL)
313		return -1;
314	iface = find_interface(ifn);
315	if (iface == NULL)
316		return 1;
317	rta = (struct rtattr *) IFA_RTA(ifa);
318	len = NLMSG_PAYLOAD(nlm, sizeof(*ifa));
319	addr.s_addr = dest.s_addr = INADDR_ANY;
320	dest.s_addr = INADDR_ANY;
321	inet_cidrtoaddr(ifa->ifa_prefixlen, &net);
322	while (RTA_OK(rta, len)) {
323		switch (rta->rta_type) {
324		case IFA_ADDRESS:
325			if (iface->flags & IFF_POINTOPOINT) {
326				memcpy(&dest.s_addr, RTA_DATA(rta),
327				    sizeof(addr.s_addr));
328			}
329			break;
330		case IFA_LOCAL:
331			memcpy(&addr.s_addr, RTA_DATA(rta),
332			    sizeof(addr.s_addr));
333			break;
334		}
335		rta = RTA_NEXT(rta, len);
336	}
337	handle_ifa(nlm->nlmsg_type, ifn, &addr, &net, &dest);
338	return 1;
339}
340
341static int
342link_netlink(struct nlmsghdr *nlm)
343{
344	int len;
345	struct rtattr *rta;
346	struct ifinfomsg *ifi;
347	char ifn[IF_NAMESIZE + 1];
348
349	len = link_route(nlm);
350	if (len != 0)
351		return len;
352	len = link_addr(nlm);
353	if (len != 0)
354		return len;
355
356	if (nlm->nlmsg_type != RTM_NEWLINK && nlm->nlmsg_type != RTM_DELLINK)
357		return 0;
358	len = nlm->nlmsg_len - sizeof(*nlm);
359	if ((size_t)len < sizeof(*ifi)) {
360		errno = EBADMSG;
361		return -1;
362	}
363	ifi = NLMSG_DATA(nlm);
364	if (ifi->ifi_flags & IFF_LOOPBACK)
365		return 1;
366	rta = (struct rtattr *) ((char *)ifi + NLMSG_ALIGN(sizeof(*ifi)));
367	len = NLMSG_PAYLOAD(nlm, sizeof(*ifi));
368	*ifn = '\0';
369	while (RTA_OK(rta, len)) {
370		switch (rta->rta_type) {
371		case IFLA_WIRELESS:
372			/* Ignore wireless messages */
373			if (nlm->nlmsg_type == RTM_NEWLINK &&
374			    ifi->ifi_change == 0)
375				return 1;
376			break;
377		case IFLA_IFNAME:
378			strlcpy(ifn, RTA_DATA(rta), sizeof(ifn));
379			break;
380		}
381		rta = RTA_NEXT(rta, len);
382	}
383
384	if (nlm->nlmsg_type == RTM_DELLINK) {
385		handle_interface(-1, ifn);
386		return 1;
387	}
388
389	/* Bridge interfaces set IFF_LOWER_UP when they have a valid
390	 * hardware address. To trigger a valid hardware address pickup
391	 * we need to pretend that that don't exist until they have
392	 * IFF_LOWER_UP set. */
393	if (ifi->ifi_flags & IFF_MASTER && !(ifi->ifi_flags & IFF_LOWER_UP)) {
394		handle_interface(-1, ifn);
395		return 1;
396	}
397
398	handle_carrier(ifi->ifi_flags & IFF_RUNNING ? 1 : -1,
399	    ifi->ifi_flags, ifn);
400	return 1;
401}
402
403int
404manage_link(int fd)
405{
406	return get_netlink(fd, MSG_DONTWAIT, &link_netlink);
407}
408
409static int
410send_netlink(struct nlmsghdr *hdr)
411{
412	int r;
413	struct iovec iov;
414	struct msghdr msg;
415	static unsigned int seq;
416
417	memset(&iov, 0, sizeof(iov));
418	iov.iov_base = hdr;
419	iov.iov_len = hdr->nlmsg_len;
420	memset(&msg, 0, sizeof(msg));
421	msg.msg_name = &sock_nl;
422	msg.msg_namelen = sizeof(sock_nl);
423	msg.msg_iov = &iov;
424	msg.msg_iovlen = 1;
425	/* Request a reply */
426	hdr->nlmsg_flags |= NLM_F_ACK;
427	hdr->nlmsg_seq = ++seq;
428
429	if (sendmsg(sock_fd, &msg, 0) != -1)
430		r = get_netlink(sock_fd, 0, &err_netlink);
431	else
432		r = -1;
433	return r;
434}
435
436#define NLMSG_TAIL(nmsg)						\
437	((struct rtattr *)(((ptrdiff_t)(nmsg))+NLMSG_ALIGN((nmsg)->nlmsg_len)))
438
439static int
440add_attr_l(struct nlmsghdr *n, unsigned int maxlen, int type,
441    const void *data, int alen)
442{
443	int len = RTA_LENGTH(alen);
444	struct rtattr *rta;
445
446	if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
447		errno = ENOBUFS;
448		return -1;
449	}
450
451	rta = NLMSG_TAIL(n);
452	rta->rta_type = type;
453	rta->rta_len = len;
454	memcpy(RTA_DATA(rta), data, alen);
455	n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
456
457	return 0;
458}
459
460static int
461add_attr_32(struct nlmsghdr *n, unsigned int maxlen, int type, uint32_t data)
462{
463	int len = RTA_LENGTH(sizeof(data));
464	struct rtattr *rta;
465
466	if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
467		errno = ENOBUFS;
468		return -1;
469	}
470
471	rta = NLMSG_TAIL(n);
472	rta->rta_type = type;
473	rta->rta_len = len;
474	memcpy(RTA_DATA(rta), &data, sizeof(data));
475	n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
476
477	return 0;
478}
479
480struct nlma
481{
482	struct nlmsghdr hdr;
483	struct ifaddrmsg ifa;
484	char buffer[64];
485};
486
487struct nlmr
488{
489	struct nlmsghdr hdr;
490	struct rtmsg rt;
491	char buffer[256];
492};
493
494int
495if_address(const struct interface *iface,
496    const struct in_addr *address, const struct in_addr *netmask,
497    const struct in_addr *broadcast, int action)
498{
499	struct nlma *nlm;
500	int retval = 0;
501
502	nlm = xzalloc(sizeof(*nlm));
503	nlm->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
504	nlm->hdr.nlmsg_flags = NLM_F_REQUEST;
505	if (action >= 0) {
506		nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
507		nlm->hdr.nlmsg_type = RTM_NEWADDR;
508	} else
509		nlm->hdr.nlmsg_type = RTM_DELADDR;
510	if (!(nlm->ifa.ifa_index = if_nametoindex(iface->name))) {
511		free(nlm);
512		errno = ENODEV;
513		return -1;
514	}
515	nlm->ifa.ifa_family = AF_INET;
516	nlm->ifa.ifa_prefixlen = inet_ntocidr(*netmask);
517	/* This creates the aliased interface */
518	add_attr_l(&nlm->hdr, sizeof(*nlm), IFA_LABEL,
519	    iface->name, strlen(iface->name) + 1);
520	add_attr_l(&nlm->hdr, sizeof(*nlm), IFA_LOCAL,
521	    &address->s_addr, sizeof(address->s_addr));
522	if (action >= 0 && broadcast)
523		add_attr_l(&nlm->hdr, sizeof(*nlm), IFA_BROADCAST,
524		    &broadcast->s_addr, sizeof(broadcast->s_addr));
525
526	if (send_netlink(&nlm->hdr) == -1)
527		retval = -1;
528	free(nlm);
529	return retval;
530}
531
532int
533if_route(const struct rt *rt, int action)
534{
535	struct nlmr *nlm;
536	unsigned int ifindex;
537	int retval = 0;
538
539	if (!(ifindex = if_nametoindex(rt->iface->name))) {
540		errno = ENODEV;
541		return -1;
542	}
543
544	nlm = xzalloc(sizeof(*nlm));
545	nlm->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
546	nlm->hdr.nlmsg_type = RTM_NEWROUTE;
547	if (action == 0)
548		nlm->hdr.nlmsg_flags = NLM_F_REPLACE;
549	else if (action == 1)
550		nlm->hdr.nlmsg_flags = NLM_F_CREATE /*| NLM_F_EXCL*/;
551	else
552		nlm->hdr.nlmsg_type = RTM_DELROUTE;
553	nlm->hdr.nlmsg_flags |= NLM_F_REQUEST;
554	nlm->rt.rtm_family = AF_INET;
555	nlm->rt.rtm_table = RT_TABLE_MAIN;
556
557	if (action == -1 || action == -2)
558		nlm->rt.rtm_scope = RT_SCOPE_NOWHERE;
559	else {
560		nlm->hdr.nlmsg_flags |= NLM_F_CREATE /*| NLM_F_EXCL*/;
561		/* We only change route metrics for kernel routes */
562		if (rt->dest.s_addr ==
563		    (rt->iface->addr.s_addr & rt->iface->net.s_addr) &&
564		    rt->net.s_addr == rt->iface->net.s_addr)
565			nlm->rt.rtm_protocol = RTPROT_KERNEL;
566		else
567			nlm->rt.rtm_protocol = RTPROT_BOOT;
568		if (rt->gate.s_addr == INADDR_ANY ||
569		    (rt->gate.s_addr == rt->dest.s_addr &&
570			rt->net.s_addr == INADDR_BROADCAST))
571			nlm->rt.rtm_scope = RT_SCOPE_LINK;
572		else
573			nlm->rt.rtm_scope = RT_SCOPE_UNIVERSE;
574		nlm->rt.rtm_type = RTN_UNICAST;
575	}
576
577	nlm->rt.rtm_dst_len = inet_ntocidr(rt->net);
578	add_attr_l(&nlm->hdr, sizeof(*nlm), RTA_DST,
579	    &rt->dest.s_addr, sizeof(rt->dest.s_addr));
580	if (nlm->rt.rtm_protocol == RTPROT_KERNEL) {
581		add_attr_l(&nlm->hdr, sizeof(*nlm), RTA_PREFSRC,
582		    &rt->iface->addr.s_addr, sizeof(rt->iface->addr.s_addr));
583	}
584	/* If destination == gateway then don't add the gateway */
585	if (rt->dest.s_addr != rt->gate.s_addr ||
586	    rt->net.s_addr != INADDR_BROADCAST)
587		add_attr_l(&nlm->hdr, sizeof(*nlm), RTA_GATEWAY,
588		    &rt->gate.s_addr, sizeof(rt->gate.s_addr));
589
590	add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_OIF, ifindex);
591	add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_PRIORITY, rt->metric);
592
593	if (send_netlink(&nlm->hdr) == -1)
594		retval = -1;
595	free(nlm);
596	return retval;
597}
598