• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  
66  static int sock_fd;
67  static struct sockaddr_nl sock_nl;
68  
69  int
if_init(struct interface * iface)70  if_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  
95  int
if_conf(struct interface * iface)96  if_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  
115  static int
_open_link_socket(struct sockaddr_nl * nl)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  
129  int
init_sockets(void)130  init_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  
140  int
open_link_socket(void)141  open_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  
150  static int
get_netlink(int fd,int flags,int (* callback)(struct nlmsghdr *))151  get_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  
205  eexit:
206  	free(buf);
207  	return r;
208  }
209  
210  static int
err_netlink(struct nlmsghdr * nlm)211  err_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  
230  static int
link_route(struct nlmsghdr * nlm)231  link_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  
291  static int
link_addr(struct nlmsghdr * nlm)292  link_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  
341  static int
link_netlink(struct nlmsghdr * nlm)342  link_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  
403  int
manage_link(int fd)404  manage_link(int fd)
405  {
406  	return get_netlink(fd, MSG_DONTWAIT, &link_netlink);
407  }
408  
409  static int
send_netlink(struct nlmsghdr * hdr)410  send_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  
439  static int
add_attr_l(struct nlmsghdr * n,unsigned int maxlen,int type,const void * data,int alen)440  add_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  
460  static int
add_attr_32(struct nlmsghdr * n,unsigned int maxlen,int type,uint32_t data)461  add_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  
480  struct nlma
481  {
482  	struct nlmsghdr hdr;
483  	struct ifaddrmsg ifa;
484  	char buffer[64];
485  };
486  
487  struct nlmr
488  {
489  	struct nlmsghdr hdr;
490  	struct rtmsg rt;
491  	char buffer[256];
492  };
493  
494  int
if_address(const struct interface * iface,const struct in_addr * address,const struct in_addr * netmask,const struct in_addr * broadcast,int action)495  if_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  
532  int
if_route(const struct rt * rt,int action)533  if_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