1/* 2 * dhcpcd - DHCP client daemon 3 * Copyright (c) 2006-2012 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 <sys/ioctl.h> 29#include <sys/param.h> 30#include <sys/socket.h> 31#include <sys/stat.h> 32#include <sys/sysctl.h> 33#include <sys/types.h> 34 35#include <arpa/inet.h> 36#include <net/if.h> 37#include <net/if_dl.h> 38#ifdef __FreeBSD__ /* Needed so that including netinet6/in6_var.h works */ 39# include <net/if_var.h> 40#endif 41#include <net/route.h> 42#include <netinet/in.h> 43#include <netinet6/in6_var.h> 44#ifdef __DragonFly__ 45# include <netproto/802_11/ieee80211_ioctl.h> 46#elif __APPLE__ 47 /* FIXME: Add apple includes so we can work out SSID */ 48#else 49# include <net80211/ieee80211_ioctl.h> 50#endif 51 52#include <errno.h> 53#include <fnmatch.h> 54#include <stddef.h> 55#include <stdio.h> 56#include <stdlib.h> 57#include <string.h> 58#include <syslog.h> 59#include <unistd.h> 60 61#include "config.h" 62#include "common.h" 63#include "configure.h" 64#include "dhcp.h" 65#include "if-options.h" 66#include "ipv6.h" 67#include "net.h" 68 69#ifndef RT_ROUNDUP 70#define RT_ROUNDUP(a) \ 71 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 72#define RT_ADVANCE(x, n) (x += RT_ROUNDUP((n)->sa_len)) 73#endif 74 75/* FIXME: Why do we need to check for sa_family 255 */ 76#define COPYOUT(sin, sa) \ 77 sin.s_addr = ((sa) != NULL) ? \ 78 (((struct sockaddr_in *)(void *)sa)->sin_addr).s_addr : 0 79 80static int r_fd = -1; 81static char *link_buf; 82static ssize_t link_buflen; 83 84int 85if_init(_unused struct interface *iface) 86{ 87 /* BSD promotes secondary address by default */ 88 return 0; 89} 90 91int 92if_conf(_unused struct interface *iface) 93{ 94 /* No extra checks needed on BSD */ 95 return 0; 96} 97 98#ifdef DEBUG_MEMORY 99static void 100cleanup(void) 101{ 102 103 free(link_buf); 104} 105#endif 106 107int 108init_sockets(void) 109{ 110 if ((socket_afnet = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 111 return -1; 112 set_cloexec(socket_afnet); 113 if ((r_fd = socket(PF_ROUTE, SOCK_RAW, 0)) == -1) 114 return -1; 115 set_cloexec(r_fd); 116 return 0; 117} 118 119int 120getifssid(const char *ifname, char *ssid) 121{ 122 int retval = -1; 123#if defined(SIOCG80211NWID) 124 struct ifreq ifr; 125 struct ieee80211_nwid nwid; 126#elif defined(IEEE80211_IOC_SSID) 127 struct ieee80211req ireq; 128 char nwid[IEEE80211_NWID_LEN + 1]; 129#endif 130 131#if defined(SIOCG80211NWID) /* NetBSD */ 132 memset(&ifr, 0, sizeof(ifr)); 133 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 134 memset(&nwid, 0, sizeof(nwid)); 135 ifr.ifr_data = (void *)&nwid; 136 if (ioctl(socket_afnet, SIOCG80211NWID, &ifr) == 0) { 137 retval = nwid.i_len; 138 memcpy(ssid, nwid.i_nwid, nwid.i_len); 139 ssid[nwid.i_len] = '\0'; 140 } 141#elif defined(IEEE80211_IOC_SSID) /* FreeBSD */ 142 memset(&ireq, 0, sizeof(ireq)); 143 strlcpy(ireq.i_name, ifname, sizeof(ireq.i_name)); 144 ireq.i_type = IEEE80211_IOC_SSID; 145 ireq.i_val = -1; 146 memset(nwid, 0, sizeof(nwid)); 147 ireq.i_data = &nwid; 148 if (ioctl(socket_afnet, SIOCG80211, &ireq) == 0) { 149 retval = ireq.i_len; 150 memcpy(ssid, nwid, ireq.i_len); 151 ssid[ireq.i_len] = '\0'; 152 } 153#endif 154 return retval; 155} 156 157int 158if_address(const struct interface *iface, const struct in_addr *address, 159 const struct in_addr *netmask, const struct in_addr *broadcast, 160 int action) 161{ 162 struct ifaliasreq ifa; 163 union { 164 struct sockaddr *sa; 165 struct sockaddr_in *sin; 166 } _s; 167 168 memset(&ifa, 0, sizeof(ifa)); 169 strlcpy(ifa.ifra_name, iface->name, sizeof(ifa.ifra_name)); 170 171#define ADDADDR(_var, _addr) { \ 172 _s.sa = &_var; \ 173 _s.sin->sin_family = AF_INET; \ 174 _s.sin->sin_len = sizeof(*_s.sin); \ 175 memcpy(&_s.sin->sin_addr, _addr, sizeof(_s.sin->sin_addr)); \ 176 } 177 178 ADDADDR(ifa.ifra_addr, address); 179 ADDADDR(ifa.ifra_mask, netmask); 180 if (action >= 0 && broadcast) { 181 ADDADDR(ifa.ifra_broadaddr, broadcast); 182 } 183#undef ADDADDR 184 185 return ioctl(socket_afnet, 186 action < 0 ? SIOCDIFADDR : SIOCAIFADDR, &ifa); 187} 188 189int 190if_route(const struct rt *rt, int action) 191{ 192 union sockunion { 193 struct sockaddr sa; 194 struct sockaddr_in sin; 195 struct sockaddr_dl sdl; 196 struct sockaddr_storage ss; 197 } su; 198 struct rtm 199 { 200 struct rt_msghdr hdr; 201 char buffer[sizeof(su) * 4]; 202 } rtm; 203 char *bp = rtm.buffer; 204 size_t l; 205 int retval = 0; 206 207#define ADDSU { \ 208 l = RT_ROUNDUP(su.sa.sa_len); \ 209 memcpy(bp, &su, l); \ 210 bp += l; \ 211 } 212#define ADDADDR(addr) { \ 213 memset(&su, 0, sizeof(su)); \ 214 su.sin.sin_family = AF_INET; \ 215 su.sin.sin_len = sizeof(su.sin); \ 216 (&su.sin)->sin_addr = *addr; \ 217 ADDSU; \ 218 } 219 220 memset(&rtm, 0, sizeof(rtm)); 221 rtm.hdr.rtm_version = RTM_VERSION; 222 rtm.hdr.rtm_seq = 1; 223 if (action == 0) 224 rtm.hdr.rtm_type = RTM_CHANGE; 225 else if (action > 0) 226 rtm.hdr.rtm_type = RTM_ADD; 227 else 228 rtm.hdr.rtm_type = RTM_DELETE; 229 rtm.hdr.rtm_flags = RTF_UP; 230 /* None interface subnet routes are static. */ 231 if (rt->gate.s_addr != INADDR_ANY || 232 rt->net.s_addr != rt->iface->net.s_addr || 233 rt->dest.s_addr != (rt->iface->addr.s_addr & rt->iface->net.s_addr)) 234 rtm.hdr.rtm_flags |= RTF_STATIC; 235 rtm.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY; 236 if (rt->dest.s_addr == rt->gate.s_addr && 237 rt->net.s_addr == INADDR_BROADCAST) 238 rtm.hdr.rtm_flags |= RTF_HOST; 239 else { 240 rtm.hdr.rtm_addrs |= RTA_NETMASK; 241 if (rtm.hdr.rtm_flags & RTF_STATIC) 242 rtm.hdr.rtm_flags |= RTF_GATEWAY; 243 if (action >= 0) 244 rtm.hdr.rtm_addrs |= RTA_IFA; 245 } 246 247 ADDADDR(&rt->dest); 248 if (rtm.hdr.rtm_flags & RTF_HOST || 249 !(rtm.hdr.rtm_flags & RTF_STATIC)) 250 { 251 /* Make us a link layer socket for the host gateway */ 252 memset(&su, 0, sizeof(su)); 253 su.sdl.sdl_len = sizeof(struct sockaddr_dl); 254 link_addr(rt->iface->name, &su.sdl); 255 ADDSU; 256 } else 257 ADDADDR(&rt->gate); 258 259 if (rtm.hdr.rtm_addrs & RTA_NETMASK) 260 ADDADDR(&rt->net); 261 262 /* IFP here if we need it */ 263 264 if (rtm.hdr.rtm_addrs & RTA_IFA) 265 ADDADDR(&rt->iface->addr); 266 267#undef ADDADDR 268#undef ADDSU 269 270 rtm.hdr.rtm_msglen = l = bp - (char *)&rtm; 271 if (write(r_fd, &rtm, l) == -1) 272 retval = -1; 273 return retval; 274} 275 276int 277if_address6(const struct interface *ifp, const struct ipv6_addr *a, int action) 278{ 279 struct in6_aliasreq ifa; 280 struct in6_addr mask; 281 282 memset(&ifa, 0, sizeof(ifa)); 283 strlcpy(ifa.ifra_name, ifp->name, sizeof(ifa.ifra_name)); 284 285#define ADDADDR(v, addr) { \ 286 (v)->sin6_family = AF_INET6; \ 287 (v)->sin6_len = sizeof(*v); \ 288 (v)->sin6_addr = *addr; \ 289 } 290 291 ADDADDR(&ifa.ifra_addr, &a->addr); 292 ipv6_mask(&mask, a->prefix_len); 293 ADDADDR(&ifa.ifra_prefixmask, &mask); 294 ifa.ifra_lifetime.ia6t_vltime = a->prefix_vltime; 295 ifa.ifra_lifetime.ia6t_pltime = a->prefix_pltime; 296#undef ADDADDR 297 298 return ioctl(socket_afnet6, 299 action < 0 ? SIOCDIFADDR_IN6 : SIOCAIFADDR_IN6, &ifa); 300} 301 302int 303if_route6(const struct rt6 *rt, int action) 304{ 305 union sockunion { 306 struct sockaddr sa; 307 struct sockaddr_in6 sin; 308 struct sockaddr_dl sdl; 309 struct sockaddr_storage ss; 310 } su; 311 struct rtm 312 { 313 struct rt_msghdr hdr; 314 char buffer[sizeof(su) * 4]; 315 } rtm; 316 char *bp = rtm.buffer; 317 size_t l; 318 int retval = 0; 319 320/* KAME based systems want to store the scope inside the sin6_addr 321 * for link local addreses */ 322#ifdef __KAME__ 323#define SCOPE { \ 324 if (IN6_IS_ADDR_LINKLOCAL(&su.sin.sin6_addr)) { \ 325 *(uint16_t *)(void *)&su.sin.sin6_addr.s6_addr[2] = \ 326 htons(su.sin.sin6_scope_id); \ 327 su.sin.sin6_scope_id = 0; \ 328 } \ 329 } 330#else 331#define SCOPE 332#endif 333 334#define ADDSU { \ 335 l = RT_ROUNDUP(su.sa.sa_len); \ 336 memcpy(bp, &su, l); \ 337 bp += l; \ 338 } 339#define ADDADDRS(addr, scope) { \ 340 memset(&su, 0, sizeof(su)); \ 341 su.sin.sin6_family = AF_INET6; \ 342 su.sin.sin6_len = sizeof(su.sin); \ 343 (&su.sin)->sin6_addr = *addr; \ 344 su.sin.sin6_scope_id = scope; \ 345 SCOPE; \ 346 ADDSU; \ 347 } 348#define ADDADDR(addr) ADDADDRS(addr, 0) 349 350 memset(&rtm, 0, sizeof(rtm)); 351 rtm.hdr.rtm_version = RTM_VERSION; 352 rtm.hdr.rtm_seq = 1; 353 if (action == 0) 354 rtm.hdr.rtm_type = RTM_CHANGE; 355 else if (action > 0) 356 rtm.hdr.rtm_type = RTM_ADD; 357 else 358 rtm.hdr.rtm_type = RTM_DELETE; 359 360 rtm.hdr.rtm_flags = RTF_UP; 361 /* None interface subnet routes are static. */ 362 if (IN6_IS_ADDR_UNSPECIFIED(&rt->dest) && 363 IN6_IS_ADDR_UNSPECIFIED(&rt->net)) 364 rtm.hdr.rtm_flags |= RTF_GATEWAY; 365 else 366 rtm.hdr.rtm_flags |= RTF_CLONING; 367 368 rtm.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; 369// if (action >= 0) 370// rtm.hdr.rtm_addrs |= RTA_IFA; 371 372 ADDADDR(&rt->dest); 373 if (rtm.hdr.rtm_flags & (RTF_HOST | RTF_CLONING)) { 374 /* Make us a link layer socket for the host gateway */ 375 memset(&su, 0, sizeof(su)); 376 su.sdl.sdl_len = sizeof(struct sockaddr_dl); 377 link_addr(rt->iface->name, &su.sdl); 378 ADDSU; 379 } else 380 ADDADDRS(&rt->gate, rt->iface->index); 381 382 if (rtm.hdr.rtm_addrs & RTA_NETMASK) { 383 if (rtm.hdr.rtm_flags & RTF_GATEWAY) { 384 memset(&su, 0, sizeof(su)); 385 su.sin.sin6_family = AF_INET6; 386 ADDSU; 387 } else 388 ADDADDR(&rt->net); 389 } 390 391 /* IFP here if we need it */ 392 /* IFA here if we need it */ 393 394#undef ADDADDR 395#undef ADDSU 396#undef SCOPE 397 398 if (action >= 0 && rt->mtu) { 399 rtm.hdr.rtm_inits |= RTV_MTU; 400 rtm.hdr.rtm_rmx.rmx_mtu = rt->mtu; 401 } 402 403 rtm.hdr.rtm_msglen = l = bp - (char *)&rtm; 404 if (write(r_fd, &rtm, l) == -1) 405 retval = -1; 406 return retval; 407} 408 409int 410open_link_socket(void) 411{ 412 int fd; 413 414#ifdef DEBUG_MEMORY 415 if (link_buf == NULL) 416 atexit(cleanup); 417#endif 418 419 fd = socket(PF_ROUTE, SOCK_RAW, 0); 420 if (fd != -1) { 421 set_cloexec(fd); 422 set_nonblock(fd); 423 } 424 return fd; 425} 426 427static void 428get_addrs(int type, char *cp, struct sockaddr **sa) 429{ 430 int i; 431 432 for (i = 0; i < RTAX_MAX; i++) { 433 if (type & (1 << i)) { 434 sa[i] = (struct sockaddr *)cp; 435#ifdef DEBUG 436 printf ("got %d %d %s\n", i, sa[i]->sa_family, 437 inet_ntoa(((struct sockaddr_in *)sa[i])-> 438 sin_addr)); 439#endif 440 RT_ADVANCE(cp, sa[i]); 441 } else 442 sa[i] = NULL; 443 } 444} 445 446int 447manage_link(int fd) 448{ 449 char *p, *e, *cp; 450 char ifname[IF_NAMESIZE]; 451 ssize_t bytes; 452 struct rt_msghdr *rtm; 453 struct if_announcemsghdr *ifan; 454 struct if_msghdr *ifm; 455 struct ifa_msghdr *ifam; 456 struct rt rt; 457 struct sockaddr *sa, *rti_info[RTAX_MAX]; 458 int len; 459#ifdef RTM_CHGADDR 460 struct sockaddr_dl sdl; 461 unsigned char *hwaddr; 462#endif 463 464 for (;;) { 465 if (ioctl(fd, FIONREAD, &len) == -1) 466 return -1; 467 if (link_buflen < len) { 468 p = realloc(link_buf, len); 469 if (p == NULL) 470 return -1; 471 link_buf = p; 472 link_buflen = len; 473 } 474 bytes = read(fd, link_buf, link_buflen); 475 if (bytes == -1) { 476 if (errno == EAGAIN) 477 return 0; 478 if (errno == EINTR) 479 continue; 480 return -1; 481 } 482 e = link_buf + bytes; 483 for (p = link_buf; p < e; p += rtm->rtm_msglen) { 484 rtm = (struct rt_msghdr *)(void *)p; 485 switch(rtm->rtm_type) { 486#ifdef RTM_IFANNOUNCE 487 case RTM_IFANNOUNCE: 488 ifan = (struct if_announcemsghdr *)(void *)p; 489 switch(ifan->ifan_what) { 490 case IFAN_ARRIVAL: 491 handle_interface(1, ifan->ifan_name); 492 break; 493 case IFAN_DEPARTURE: 494 handle_interface(-1, ifan->ifan_name); 495 break; 496 } 497 break; 498#endif 499 case RTM_IFINFO: 500 ifm = (struct if_msghdr *)(void *)p; 501 memset(ifname, 0, sizeof(ifname)); 502 if (!(if_indextoname(ifm->ifm_index, ifname))) 503 break; 504 switch (ifm->ifm_data.ifi_link_state) { 505 case LINK_STATE_DOWN: 506 len = -1; 507 break; 508 case LINK_STATE_UP: 509 len = 1; 510 break; 511 default: 512 /* handle_carrier will re-load 513 * the interface flags and check for 514 * IFF_RUNNING as some drivers that 515 * don't handle link state also don't 516 * set IFF_RUNNING when this routing 517 * message is generated. 518 * As such, it is a race ...*/ 519 len = 0; 520 break; 521 } 522 handle_carrier(len, ifm->ifm_flags, ifname); 523 break; 524 case RTM_DELETE: 525 if (~rtm->rtm_addrs & 526 (RTA_DST | RTA_GATEWAY | RTA_NETMASK)) 527 break; 528 if (rtm->rtm_pid == getpid()) 529 break; 530 cp = (char *)(void *)(rtm + 1); 531 sa = (struct sockaddr *)(void *)cp; 532 if (sa->sa_family != AF_INET) 533 break; 534 get_addrs(rtm->rtm_addrs, cp, rti_info); 535 rt.iface = NULL; 536 rt.next = NULL; 537 COPYOUT(rt.dest, rti_info[RTAX_DST]); 538 COPYOUT(rt.net, rti_info[RTAX_NETMASK]); 539 COPYOUT(rt.gate, rti_info[RTAX_GATEWAY]); 540 route_deleted(&rt); 541 break; 542#ifdef RTM_CHGADDR 543 case RTM_CHGADDR: /* FALLTHROUGH */ 544#endif 545 case RTM_DELADDR: /* FALLTHROUGH */ 546 case RTM_NEWADDR: 547 ifam = (struct ifa_msghdr *)(void *)p; 548 if (!if_indextoname(ifam->ifam_index, ifname)) 549 break; 550 cp = (char *)(void *)(ifam + 1); 551 get_addrs(ifam->ifam_addrs, cp, rti_info); 552 if (rti_info[RTAX_IFA] == NULL) 553 break; 554 switch (rti_info[RTAX_IFA]->sa_family) { 555#ifdef RTM_CHGADDR 556 case AF_LINK: 557 if (rtm->rtm_type != RTM_CHGADDR) 558 break; 559 memcpy(&sdl, rti_info[RTAX_IFA], 560 rti_info[RTAX_IFA]->sa_len); 561 hwaddr = xmalloc(sdl.sdl_alen); 562 memcpy(hwaddr, LLADDR(&sdl), 563 sdl.sdl_alen); 564 handle_hwaddr(ifname, hwaddr, 565 sdl.sdl_alen); 566 break; 567#endif 568 case AF_INET: 569 case 255: /* FIXME: Why 255? */ 570 COPYOUT(rt.dest, rti_info[RTAX_IFA]); 571 COPYOUT(rt.net, rti_info[RTAX_NETMASK]); 572 COPYOUT(rt.gate, rti_info[RTAX_BRD]); 573 handle_ifa(rtm->rtm_type, ifname, 574 &rt.dest, &rt.net, &rt.gate); 575 break; 576 } 577 break; 578 } 579 } 580 } 581} 582